@Injectable({ providedIn: 'root' })
export class TitleBarService {
hasLoadedFinshed?: boolean;
constructor() {}
}
@Injectable({
providedIn: 'root',
deps: [TitleBarService]
})
export class TitleBarGuard {
constructor(private titlebar: TitleBarService) {}
canActivate(
route: ActivatedRouteSnapshot,
_: RouterStateSnapshot
): Promise<boolean> | Observable<boolean> | null {
return new Observable<boolean>(obs => {
if (this.titlebar.hasLoadedFinshed) {
obs.next(true);
obs.complete();
}
});
}
}
+》然后在路由模块下添加路由守卫。canActivate: [TitleBarGuard]
=》然后在 titlebar.ts 添加如下:this.titleBar.hasLoadedFinshed = true;。
=》路由守卫控制是否显示该页面
html
<h2>Student Details:</h2>
<div *ngFor="let stud of students">
<a routerLink="/studentList/{{stud.id}}/{{stud.name}}/{{stud.marks}}"> Id : {{stud.id}}, Name : {{stud.name}} </a>
</div>
<br>
<p>Currently Selected :</p>
<p>Id: {{student.id}}</p>
<p>Name: {{student.name}}</p>
mark: {{student.marks}}
<p>x: {{x}}</p>
y: {{y}}
ts
export class DetailComponent implements OnInit {
constructor(private route: ActivatedRoute, private router: Router) {
// this.route.paramMap.subscribe(q => { 会改变
// this.x = q.get("id");
// });
}
x: string;
y: any;
public student = {
id: "",
name: "",
marks: ""
};
public students = [
{ id: 1001, name: "Irshad", marks: 90 },
{ id: 1002, name: "Imran", marks: 80 },
{ id: 1003, name: "Rahul", marks: 70 },
{ id: 1004, name: "Ajay", marks: 85 },
{ id: 1005, name: "Sunny", marks: 60 }
];
ngOnInit() {
// this.x = this.route.snapshot.paramMap.get("id"); // 不会改变
// this.route.paramMap.pipe( 为何没有打印出x 的值
// switchMap(p => {
// return (this.x = p.get("id"));
// })
// );
// console.log(this.x);
this.route.paramMap.subscribe((params: ParamMap) => {
this.student.id = params.get("id"); // 会改变
this.student.name = params.get("name");
this.student.marks = params.get("marks");
this.y = this.route.snapshot.paramMap.keys[0];
if (params.get("name") === "Aja") {
console.log("yes");
} else {
console.log("no");
}
});
}
}
路由发射事件:【借助服务 service】
链接🔗:https://stackoverflow.com/questions/37662456/angular-2-output-from-router-outlet/41989983#41989983
服务:
import { Injectable } from '@angular/core';
import { Subject } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class AnotherPageService {
constructor() {}
private changePageSource = new Subject<any>();
changePage$ = this.changePageSource.asObservable();
changePageClicked(change: boolean) {
this.changePageSource.next(change);
}
}
路由的组件:
toViewing() {
this.router.navigate(['/main', 'viewing']);
this.anotherPageService.changePageClicked(false);
}
点击路由组件上的 toViewing() 事件 触发到的那个组件:
constructor(
private anotherPageService: AnotherPageService
) {
this.anotherPageService.changePage$.subscribe(
x => {
this.informationDisplay = x;
},
e => console.error(e)
);
}
路由获取当前 url 信息
知识点:instanceof
运算符用于检测构造函数的 prototype
属性是否出现在某个实例对象的原型链上。
During each navigation, the Router
emits navigation events through the Router.events
property.
以下列出几种方法:
import { Router,NavigationEnd } from '@angular/router';
constructor(private route:Router){
this.routeEvent(this.route);
}
routeEvent(router: Router){
router.events.subscribe(e => {
if(e instanceof NavigationEnd){
console.log(e)
}
});
}
router.events
.pipe(filter(e => e instanceof NavigationStart))
.subscribe((e: any) => {
if (e.url.indexOf('/exam') === 0) {
this.mainOrExam = false;
} else {
this.mainOrExam = true;
}
});
router.events.subscribe(
() => {
const currentRouter = this.route.snapshot.firstChild
? this.route.snapshot.firstChild.url[0].toString()
: null;
if (currentRouter === 'main') {
// if (router.url.indexOf('/main') === 0) {
this.mainOrExam = true;
} else {
// } else if (router.url.indexOf('/exam') === 0) {
this.mainOrExam = false;
}
},
e => console.log(e)
);
router.events
.pipe(
map(() => this.route.root.firstChild),
switchMap(firstChild =>
firstChild
? firstChild.paramMap.pipe(map(paramMap => paramMap.keys[0]))
: of(null)
)
)
.subscribe(x => {
if (x === 'studyId') {
this.mainOrExam = false;
} else {
this.mainOrExam = true;
}
});
把对象字面量赋给一个可订阅的流 Subject
export interface StudyCardExportMeta {
studyId: string;
patientId: string;
// card_state: 'mocked' | 'real';
}
idBundle?: Observable<StudyCardExportMeta>; //TODO: repeat 'idBundle' with 'subjectIdBundle$'
subjectIdBundle$: BehaviorSubject<StudyCardExportMeta> = new BehaviorSubject<
StudyCardExportMeta
>({
studyId: '',
patientId: ''
});
studyIdBundles?: StudyCardExportMeta = {
studyId: '',
patientId: ''
};
this.route.root.firstChild
? this.route.root.firstChild.paramMap
.pipe(
map(bundle => {
this.studyIdBundles = {
studyId: bundle.get('studyId'),
patientId: bundle.get('patientId')
} as StudyCardExportMeta;
})
)
.subscribe(
() => {
if (this.studyIdBundles) {
this.subjectIdBundle$.next(this.studyIdBundles);
}
this.idBundle = this.subjectIdBundle$;
},
e => console.log(e)
)
: of(null);
this.route.root.firstChild
? this.route.root.firstChild.paramMap
.pipe(
switchMap(_ => {
return of({
studyId: _.get('studyId'),
patientId: _.get('patientId')
} as StudyCardExportMeta);
})
)
.subscribe(
_ => {
this.studyIdBundles = _;
this.subjectIdBundle$.next(this.studyIdBundles);
this.idBundle = this.subjectIdBundle$;
},
e => console.error(e)
)
: of(null);
获取整个url:
this.router.events.subscribe(x => console.log("@@@: ",this.router.url.toString()))
加载子路由时模板渲染2次的解决方法: