Skip to content

Commit 147d35a

Browse files
Sean Perkinssis0k0
Sean Perkins
authored andcommitted
feat: add exportAs logic for isActive on routerLinkActive directive (#940)
implements #928
1 parent f0ed7f6 commit 147d35a

File tree

4 files changed

+46
-20
lines changed

4 files changed

+46
-20
lines changed

Diff for: nativescript-angular/router/ns-router-link-active.ts

+29-7
Original file line numberDiff line numberDiff line change
@@ -53,12 +53,16 @@ import { NSRouterLink } from "./ns-router-link";
5353
*
5454
* @stable
5555
*/
56-
@Directive({ selector: "[nsRouterLinkActive]" })
56+
@Directive({
57+
selector: "[nsRouterLinkActive]",
58+
exportAs: "routerLinkActive",
59+
})
5760
export class NSRouterLinkActive implements OnChanges, OnDestroy, AfterContentInit { // tslint:disable-line:max-line-length directive-class-suffix
5861
@ContentChildren(NSRouterLink) links: QueryList<NSRouterLink>;
5962

6063
private classes: string[] = [];
6164
private subscription: Subscription;
65+
private active: boolean = false;
6266

6367
@Input() nsRouterLinkActiveOptions: { exact: boolean } = { exact: false };
6468

@@ -70,6 +74,10 @@ export class NSRouterLinkActive implements OnChanges, OnDestroy, AfterContentIni
7074
});
7175
}
7276

77+
get isActive(): boolean {
78+
return this.active;
79+
}
80+
7381
ngAfterContentInit(): void {
7482
this.links.changes.subscribe(() => this.update());
7583
this.update();
@@ -91,12 +99,16 @@ export class NSRouterLinkActive implements OnChanges, OnDestroy, AfterContentIni
9199
if (!this.links) {
92100
return;
93101
}
94-
95-
const currentUrlTree = this.router.parseUrl(this.router.url);
96-
const isActiveLinks = this.reduceList(currentUrlTree, this.links);
97-
this.classes.forEach(
98-
c => this.renderer.setElementClass(
99-
this.element.nativeElement, c, isActiveLinks));
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(
108+
c => this.renderer.setElementClass(
109+
this.element.nativeElement, c, isActiveLinks));
110+
}
111+
Promise.resolve(hasActiveLinks).then(active => this.active = active);
100112
}
101113

102114
private reduceList(currentUrlTree: UrlTree, q: QueryList<any>): boolean {
@@ -106,4 +118,14 @@ export class NSRouterLinkActive implements OnChanges, OnDestroy, AfterContentIni
106118
this.nsRouterLinkActiveOptions.exact);
107119
}, false);
108120
}
121+
122+
private isLinkActive(router: Router): (link: NSRouterLink) => boolean {
123+
return (link: NSRouterLink) =>
124+
router.isActive(link.urlTree, this.nsRouterLinkActiveOptions.exact);
125+
}
126+
127+
private hasActiveLinks(): boolean {
128+
return this.links.some(this.isLinkActive(this.router));
129+
}
130+
109131
}

Diff for: ng-sample/app/app.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -132,14 +132,14 @@ const customPageFactoryProvider = {
132132
// platformNativeScriptDynamic().bootstrapModule(makeExampleModule(ActionBarTest));
133133

134134
// router
135-
// platformNativeScriptDynamic().bootstrapModule(makeExampleModule(RouterOutletAppComponent));
135+
platformNativeScriptDynamic().bootstrapModule(makeExampleModule(RouterOutletAppComponent));
136136
// platformNativeScriptDynamic().bootstrapModule(makeExampleModule(PageRouterOutletAppComponent));
137137
// platformNativeScriptDynamic().bootstrapModule(makeExampleModule(PageRouterOutletNestedAppComponent));
138138
// platformNativeScriptDynamic().bootstrapModule(makeExampleModule(ClearHistoryAppComponent));
139139
// platformNativeScriptDynamic().bootstrapModule(makeExampleModule(LoginAppComponent));
140140

141141
// animations
142-
platformNativeScriptDynamic().bootstrapModule(makeExampleModule(AnimationStatesTest));
142+
// platformNativeScriptDynamic().bootstrapModule(makeExampleModule(AnimationStatesTest));
143143
// platformNativeScriptDynamic().bootstrapModule(makeExampleModule(AnimationStatesMultiTest));
144144
// platformNativeScriptDynamic().bootstrapModule(makeExampleModule(AnimationNgClassTest));
145145
// platformNativeScriptDynamic().bootstrapModule(makeExampleModule(AnimationKeyframesTest));

Diff for: ng-sample/app/examples/router/router-outlet-test.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -49,14 +49,14 @@ class SecondComponent implements OnInit, OnDestroy {
4949
template: `
5050
<StackLayout>
5151
<StackLayout class="nav">
52-
<Button text="First" nsRouterLinkActive="active" nsRouterLink="/first"></Button>
53-
<Button text="Second(1)" nsRouterLinkActive="active" nsRouterLink="/second/1"></Button>
52+
<Button text="First" [class.rlaActive]="rla.isActive" nsRouterLinkActive="active" nsRouterLink="/first" #rla="routerLinkActive"></Button>
53+
<Button text="Second(1)" nsRouterLinkActive="active" nsRouterLink="/second/1"></Button>
5454
<Button text="Second(2)"
5555
nsRouterLinkActive="active"
5656
[nsRouterLink]="['/second', '2' ]">
5757
</Button>
5858
</StackLayout>
59-
59+
6060
<router-outlet></router-outlet>
6161
</StackLayout>
6262
`

Diff for: ng-sample/app/examples/router/styles.css

+12-8
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55
}
66

77
.subtitle {
8-
font-size: 20;
9-
horizontal-align: center;
8+
font-size: 20;
9+
horizontal-align: center;
1010
margin: 10;
1111
}
1212

@@ -53,17 +53,21 @@ button {
5353
horizontal-align: center;
5454
}
5555

56-
.odd {
57-
background-color: white;
56+
.odd {
57+
background-color: white;
5858
margin: 2;
5959
}
6060

61-
.even {
62-
background-color: whitesmoke;
63-
margin: 2;
61+
.even {
62+
background-color: whitesmoke;
63+
margin: 2;
6464
}
6565

6666
.stretch {
6767
horizontal-align: stretch;
6868
margin: 0 10;
69-
}
69+
}
70+
71+
.rlaActive {
72+
color:blue;
73+
}

0 commit comments

Comments
 (0)