Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 13a3562

Browse files
fix(ivy): nsRouterLinkActive works on nsRouterLink (#2322)
1 parent 5632898 commit 13a3562

File tree

2 files changed

+61
-27
lines changed

2 files changed

+61
-27
lines changed

‎nativescript-angular/router/ns-router-link-active.ts

Lines changed: 49 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
1-
import { AfterContentInit, ContentChildren, Directive, ElementRef, Input, OnChanges, OnDestroy, QueryList, Renderer2 } from '@angular/core';
2-
import { Subscription } from 'rxjs';
1+
import { AfterContentInit, ChangeDetectorRef,ContentChildren, Directive, ElementRef, Input, OnChanges, OnDestroy,Optional, QueryList, Renderer2 } from '@angular/core';
2+
import { from,of,Subscription } from 'rxjs';
33

44
import { NavigationEnd, Router, UrlTree } from '@angular/router';
55
import { containsTree } from './private-imports/router-url-tree';
66

77
import { NSRouterLink } from './ns-router-link';
8+
import { mergeAll } from 'rxjs/operators';
89

910
/**
1011
* The NSRouterLinkActive directive lets you add a CSS class to an element when the link"s route
@@ -54,16 +55,17 @@ import { NSRouterLink } from './ns-router-link';
5455
})
5556
export class NSRouterLinkActive implements OnChanges, OnDestroy, AfterContentInit {
5657
// tslint:disable-line:max-line-length directive-class-suffix
57-
@ContentChildren(NSRouterLink) links: QueryList<NSRouterLink>;
58+
@ContentChildren(NSRouterLink,{descendants: true}) links: QueryList<NSRouterLink>;
5859

5960
private classes: string[] = [];
60-
private subscription: Subscription;
61+
private routerEventsSubscription: Subscription;
62+
private linkInputChangesSubscription?: Subscription;
6163
private active: boolean = false;
6264

6365
@Input() nsRouterLinkActiveOptions: { exact: boolean } = { exact: false };
6466

65-
constructor(private router: Router, private element: ElementRef, private renderer: Renderer2) {
66-
this.subscription = router.events.subscribe((s) => {
67+
constructor(private router: Router, private element: ElementRef, private renderer: Renderer2,privatereadonlycdr: ChangeDetectorRef, @Optional()privatelink?: NSRouterLink) {
68+
this.routerEventsSubscription = router.events.subscribe((s) => {
6769
if (s instanceof NavigationEnd) {
6870
this.update();
6971
}
@@ -75,8 +77,25 @@ export class NSRouterLinkActive implements OnChanges, OnDestroy, AfterContentIni
7577
}
7678

7779
ngAfterContentInit(): void {
78-
this.links.changes.subscribe(() => this.update());
79-
this.update();
80+
// `of(null)` is used to force subscribe body to execute once immediately (like `startWith`).
81+
from([this.links.changes, of(null)])
82+
.pipe(mergeAll())
83+
.subscribe((_) => {
84+
this.update();
85+
this.subscribeToEachLinkOnChanges();
86+
});
87+
}
88+
89+
private subscribeToEachLinkOnChanges() {
90+
this.linkInputChangesSubscription?.unsubscribe();
91+
const allLinkChanges = [...this.links.toArray(), this.link].filter((link): link is NSRouterLink => !!link).map((link) => link.onChanges);
92+
this.linkInputChangesSubscription = from(allLinkChanges)
93+
.pipe(mergeAll())
94+
.subscribe((link) => {
95+
if (this.isActive !== this.isLinkActive(this.router)(link)) {
96+
this.update();
97+
}
98+
});
8099
}
81100

82101
@Input('nsRouterLinkActive')
@@ -92,30 +111,34 @@ export class NSRouterLinkActive implements OnChanges, OnDestroy, AfterContentIni
92111
this.update();
93112
}
94113
ngOnDestroy(): any {
95-
this.subscription.unsubscribe();
114+
this.routerEventsSubscription.unsubscribe();
115+
this.linkInputChangesSubscription?.unsubscribe();
96116
}
97117

98118
private update(): void {
99119
if (!this.links) {
100120
return;
101121
}
102-
const hasActiveLinks = this.hasActiveLinks();
103-
// react only when status has changed to prevent unnecessary dom updates
104-
if (this.active !== hasActiveLinks) {
105-
const currentUrlTree = this.router.parseUrl(this.router.url);
106-
const isActiveLinks = this.reduceList(currentUrlTree, this.links);
107-
this.classes.forEach((c) => {
108-
if (isActiveLinks) {
109-
this.renderer.addClass(this.element.nativeElement, c);
110-
} else {
111-
this.renderer.removeClass(this.element.nativeElement, c);
112-
}
113-
});
114-
}
115-
Promise.resolve(hasActiveLinks).then((active) => (this.active = active));
122+
Promise.resolve().then(() => {
123+
const hasActiveLinks = this.hasActiveLinks();
124+
if (this.active !== hasActiveLinks) {
125+
this.active = hasActiveLinks;
126+
const currentUrlTree = this.router.parseUrl(this.router.url);
127+
const links = this.link ? [...this.links.toArray(), this.link] : this.links;
128+
const isActiveLinks = this.reduceList(currentUrlTree, links);
129+
this.cdr.markForCheck();
130+
this.classes.forEach((c) => {
131+
if (isActiveLinks) {
132+
this.renderer.addClass(this.element.nativeElement, c);
133+
} else {
134+
this.renderer.removeClass(this.element.nativeElement, c);
135+
}
136+
});
137+
}
138+
});
116139
}
117140

118-
private reduceList(currentUrlTree: UrlTree, q: QueryList<any>): boolean {
141+
private reduceList(currentUrlTree: UrlTree, q: QueryList<any>|Array<any>): boolean {
119142
return q.reduce((res: boolean, link: NSRouterLink) => {
120143
return res || containsTree(currentUrlTree, link.urlTree, this.nsRouterLinkActiveOptions.exact);
121144
}, false);
@@ -126,6 +149,7 @@ export class NSRouterLinkActive implements OnChanges, OnDestroy, AfterContentIni
126149
}
127150

128151
private hasActiveLinks(): boolean {
129-
return this.links.some(this.isLinkActive(this.router));
152+
const isActiveCheckFn = this.isLinkActive(this.router);
153+
return (this.link && isActiveCheckFn(this.link)) || this.links.some(isActiveCheckFn);
130154
}
131155
}

‎nativescript-angular/router/ns-router-link.ts

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
1-
import { Directive, Input, ElementRef, NgZone } from '@angular/core';
1+
import { Directive, Input, ElementRef, NgZone,OnChanges,SimpleChanges } from '@angular/core';
22
import { NavigationExtras } from '@angular/router';
33
import { ActivatedRoute, Router, UrlTree } from '@angular/router';
44
import { NavigationTransition } from '@nativescript/core';
55
import { NativeScriptDebug } from '../trace';
66
import { RouterExtensions } from './router-extensions';
77
import { NavigationOptions } from './ns-location-utils';
8+
import { Subject } from 'rxjs';
89

910
// Copied from "@angular/router/src/config"
1011
export type QueryParamsHandling = 'merge' | 'preserve' | '';
@@ -34,7 +35,7 @@ export type QueryParamsHandling = 'merge' | 'preserve' | '';
3435
* And if the segment begins with `../`, the router will go up one level.
3536
*/
3637
@Directive({ selector: '[nsRouterLink]' })
37-
export class NSRouterLink {
38+
export class NSRouterLink implementsOnChanges{
3839
// tslint:disable-line:directive-class-suffix
3940
@Input() target: string;
4041
@Input() queryParams: { [k: string]: any };
@@ -50,6 +51,9 @@ export class NSRouterLink {
5051
@Input() pageTransition: boolean | string | NavigationTransition = true;
5152
@Input() pageTransitionDuration;
5253

54+
/** @internal */
55+
onChanges = new Subject<NSRouterLink>();
56+
5357
private commands: any[] = [];
5458

5559
constructor(private ngZone: NgZone, private router: Router, private navigator: RouterExtensions, private route: ActivatedRoute, private el: ElementRef) {}
@@ -75,6 +79,12 @@ export class NSRouterLink {
7579
});
7680
}
7781

82+
ngOnChanges(changes: SimpleChanges) {
83+
// This is subscribed to by `RouterLinkActive` so that it knows to update when there are changes
84+
// to the RouterLinks it's tracking.
85+
this.onChanges.next(this);
86+
}
87+
7888
@Input('nsRouterLink')
7989
set params(data: any[] | string) {
8090
if (Array.isArray(data)) {

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /