Mui*_*rik 5 javascript typescript angular
根据我的理解,在Angular 2中,如果要在不相关的组件之间传递值(即,不共享路由的组件,因此不共享父子关系),则通过共享服务执行此操作.
这就是我在Angular2应用程序中设置的内容.我正在检查一个url中是否存在一系列字符,如果存在则返回true.
isRoomRoute(routeUrl) {
if ((routeUrl.includes('staff') || routeUrl.includes('contractors'))) {
console.log('This url: ' + routeUrl + ' is a roomRoute');
return true;
} else {
console.log('This url: ' + routeUrl + ' is NOT a room route');
return false;
}
}
Run Code Online (Sandbox Code Playgroud)
在根app.component的构造函数中,我正在订阅路由事件:
constructor(private routeService: RouteService,
private router: Router) {
this.router.events.subscribe((route) => {
let routeUrl = route.url;
this.routeService.sendRoute(routeUrl);
this.routeService.isRoomRoute(routeUrl);
});
}
Run Code Online (Sandbox Code Playgroud)
...然后使用提供的URL来检查url是否包含特定字符串.每次路线更改时都会对此进行评估.
所以这一切都按预期工作.
但是,我在将该检查的结果传递给另一个不相关(非父子)组件时遇到了问题.
即使我在app.component和un-related(room.component)组件中使用共享服务(routeService),但在一个组件中工作的东西在另一个组件中不起作用.根据我的理解,这里检查的内容的"真实性"应该足以回复真实的陈述.
但是在次要的,不相关的组件中,当我调用函数时,我得到一个"未定义"错误,如下所示:
isRoomRoute() {
if (this.routeService.isRoomRoute(this.routeUrl)) {
return true;
}
}
Run Code Online (Sandbox Code Playgroud)
所以这就是我被困住的地方.基本上,关于url是否包含某个字符串的评估已经发生.现在我只需要将该检查的布尔结果传递给辅助的非相关组件.我怎样才能在Angular 2中做到最好?
您的理解是正确的,injectable共享服务是多个不相关组件之间通信的常用方式.
以下是这种用例的演练.
首先,根据您的情况,我们将监听Router事件AppComponent,获取活动路径,并将其传递给RouteService服务,以便服务可以操纵它,和/或将其提供给其他组件.
这AppComponent应该是这样的:
export class AppComponent {
constructor(private _router: Router,
private _routeService: RouteService) {
this._router.events.subscribe(event => {
if (event instanceof NavigationEnd) {
let url = event.urlAfterRedirects;
this._routeService.onActiveRouteChanged(url);
}
});
}
}
Run Code Online (Sandbox Code Playgroud)
当涉及到服务时,我们将在此处介绍BehaviorSubject作为委托,因此使用该服务的组件可以订阅服务数据更改.有关BehaviorSubject其他主题的更多信息,请访问:委托:Angular2中的EventEmitter或Observable
以下是我们共享的实现RouteService(组件需要使用服务的单个实例,因此请确保您已在根级别提供它):
@Injectable()
export class RouteService {
isRoomRouteSource: BehaviorSubject<boolean> = new BehaviorSubject(false);
constructor() { }
onActiveRouteChanged(url: string): void {
let isRoomRoute = this._isRoomRoute(url);
this.isRoomRouteSource.next(isRoomRoute);
// do other stuff needed when route changes
}
private _isRoomRoute(url: string): boolean {
return url.includes('staff') || url.includes('contractors');
}
}
Run Code Online (Sandbox Code Playgroud)
使用该服务的另一个组件的示例,并订阅我们的BehaviorSubject更改:
export class AnotherComponent {
isCurrentRouteRoomRoute: boolean;
constructor(private _routeService: RouteService) {
this._routeService.isRoomRouteSource.subscribe((isRoomRoute: boolean) => {
this.isCurrentRouteRoomRoute = isRoomRoute;
// prints whenever active route changes
console.log('Current route is room route: ', isRoomRoute);
});
}
}
Run Code Online (Sandbox Code Playgroud)
如果isRoomRouteSource没有必要订阅更改,请说我们只需要存储最后一个值,然后:
export class AnotherComponent {
isCurrentRouteRoomRoute: boolean;
constructor(private _routeService: RouteService) {
this.isCurrentRouteRoomRoute = this._routeService.isRoomRouteSource.getValue(); // returns last value stored
console.log('Current route is room route: ', this.isCurrentRouteRoomRoute);
}
}
Run Code Online (Sandbox Code Playgroud)
希望这有帮助!
| 归档时间: |
|
| 查看次数: |
4408 次 |
| 最近记录: |