Skip to content

Commit 5d21413

Browse files
committed
feat(core): added *route directive
RouteDirective provides all fields from ActivatedRoute object interface RouteContext { $implicit: ActivatedRoute; snapshot: ActivatedRouteSnapshot; url: UrlSegment[]; params: Params; queryParams: Params; fragment: string; data: Data; outlet: string; component: Type<any> | string; routeConfig: Route; root: ActivatedRoute; parent: ActivatedRoute | null; firstChild: ActivatedRoute | null; children: ActivatedRoute[]; pathFromRoot: ActivatedRoute[]; paramMap: ParamMap; queryParamMap: ParamMap; } Usage examples: *route="let route" *route="let snapshot = snapshot" *route="let url = url" *route="let params = params" *route="let queryParams = queryParams" *route="let fragment = fragment" *route="let data = data" *route="let outlet = outlet" *route="let component = component" *route="let routeConfig = routeConfig" *route="let root = root" *route="let parent = parent" *route="let firstChild = firstChild" *route="let children = children" *route="let pathFromRoot = pathFromRoot" *route="let paramMap = paramMap" *route="let queryParamMap = queryParamMap"
1 parent a5f257b commit 5d21413

8 files changed

Lines changed: 89 additions & 15 deletions

File tree

projects/platform/package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@
3838
"homepage": "https://github.com/ngxf/platform",
3939
"peerDependencies": {
4040
"@angular/common": "^6.0.0-rc.0 || ^6.0.0",
41-
"@angular/core": "^6.0.0-rc.0 || ^6.0.0"
41+
"@angular/core": "^6.0.0-rc.0 || ^6.0.0",
42+
"@angular/router": "^6.0.0-rc.0 || ^6.0.0",
43+
"rxjs": ">=6.0.0 || ^5.6.0-forward-compat.4"
4244
}
4345
}

projects/platform/src/lib/directives/http.directive.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -115,15 +115,13 @@ export class HttpDirective implements OnChanges {
115115
private execute(strategy: HttpStrategy) {
116116
const params = strategy.changes.map(field => this[field]);
117117

118-
console.log(strategy, ...params);
119-
120118
this.request(strategy.type, ...params);
121119
}
122120

123121
private request(method, ...params) {
124122
this.http[method](...params)
125123
.pipe(catchError((e) => {
126-
console.log(e);
124+
console.error(e);
127125
return of(null);
128126
}))
129127
.subscribe((data) => {
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
export * from './http.directive';
2+
export * from './route.directive';
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
import { OnDestroy, Directive, Type, TemplateRef, ViewContainerRef, EmbeddedViewRef } from '@angular/core';
2+
import { ActivatedRoute, ActivatedRouteSnapshot, UrlSegment, Params, Data, Route, ParamMap, convertToParamMap } from '@angular/router';
3+
import { Subscription } from 'rxjs';
4+
import { distinctUntilChanged } from 'rxjs/operators';
5+
6+
interface RouteContext {
7+
$implicit: ActivatedRoute;
8+
snapshot: ActivatedRouteSnapshot;
9+
url: UrlSegment[];
10+
params: Params;
11+
queryParams: Params;
12+
fragment: string;
13+
data: Data;
14+
outlet: string;
15+
component: Type<any> | string;
16+
routeConfig: Route;
17+
root: ActivatedRoute;
18+
parent: ActivatedRoute | null;
19+
firstChild: ActivatedRoute | null;
20+
children: ActivatedRoute[];
21+
pathFromRoot: ActivatedRoute[];
22+
paramMap: ParamMap;
23+
queryParamMap: ParamMap;
24+
}
25+
26+
const ASYNC_FIELDS = ['url', 'params', 'queryParams', 'fragment', 'data', 'paramMap', 'queryParamMap'];
27+
28+
@Directive({ selector: '[route]' })
29+
export class RouteDirective implements OnDestroy {
30+
private context: RouteContext = {
31+
$implicit: this.route,
32+
get snapshot() { return this.route.snapshot; },
33+
url: [],
34+
params: {},
35+
queryParams: {},
36+
fragment: null,
37+
data: null,
38+
get outlet() { return this.route.outlet; },
39+
get component() { return this.route.component; },
40+
get routeConfig() { return this.route.routeConfig; },
41+
get root() { return this.route.root; },
42+
get parent() { return this.route.parent; },
43+
get firstChild() { return this.route.firstChild; },
44+
get children() { return this.route.children; },
45+
get pathFromRoot() { return this.route.pathFromRoot; },
46+
paramMap: convertToParamMap({}),
47+
queryParamMap: convertToParamMap({})
48+
};
49+
private viewRef: EmbeddedViewRef<RouteContext> =
50+
this.viewContainerRef.createEmbeddedView(this.templateRef, this.context);
51+
private subscriptions: Subscription[] = this.attachFields(ASYNC_FIELDS);
52+
53+
constructor(
54+
private templateRef: TemplateRef<RouteContext>,
55+
private viewContainerRef: ViewContainerRef,
56+
private route: ActivatedRoute
57+
) { }
58+
59+
ngOnDestroy() {
60+
this.subscriptions.forEach((subscription) => {
61+
subscription.unsubscribe();
62+
});
63+
this.subscriptions = null;
64+
}
65+
66+
private attachFields(asyncFields: string[]): Subscription[] {
67+
return asyncFields.map(field => this.asyncAttach(field));
68+
}
69+
70+
private asyncAttach(field: string): Subscription {
71+
return this.route[field]
72+
.pipe(distinctUntilChanged())
73+
.subscribe(value => {
74+
this.context[field] = value;
75+
this.viewRef.markForCheck();
76+
});
77+
}
78+
}
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
import { NgModule } from '@angular/core';
2-
import { HttpDirective } from './directives';
2+
import { HttpDirective, RouteDirective } from './directives';
33

44
@NgModule({
55
imports: [],
6-
declarations: [HttpDirective],
7-
exports: [HttpDirective]
6+
declarations: [HttpDirective, RouteDirective],
7+
exports: [HttpDirective, RouteDirective]
88
})
99
export class NgxfModule { }

src/app/shared/shared.module.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ const COMPONENTS = [
1515
exports: [
1616
CommonModule,
1717
COMPONENTS,
18+
NgxfModule,
1819
MatToolbarModule,
1920
MatButtonModule,
2021
MatSidenavModule,
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
<app-user [username]="username | async"></app-user>
1+
<app-user *route="let params = paramMap" [username]="params.get('username')"></app-user>
Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,8 @@
11
import { Component, ChangeDetectionStrategy } from '@angular/core';
2-
import { ActivatedRoute } from '@angular/router';
3-
import { Observable } from 'rxjs';
4-
import { map, tap } from 'rxjs/operators';
52

63
@Component({
74
selector: 'app-user-view',
85
templateUrl: 'user.component.html',
96
changeDetection: ChangeDetectionStrategy.OnPush
107
})
11-
export class UserViewComponent {
12-
username: Observable<string> = this.route.paramMap.pipe(map(params => params.get('username')));
13-
constructor(private route: ActivatedRoute) {}
14-
}
8+
export class UserViewComponent {}

0 commit comments

Comments
 (0)