根据我的理解,在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; } }
在根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); }); }
...然后使用提供的URL来检查url是否包含特定字符串.每次路线更改时都会对此进行评估.
所以这一切都按预期工作.
但是,我在将该检查的结果传递给另一个不相关(非父子)组件时遇到了问题.
即使我在app.component和un-related(room.component)组件中使用共享服务(routeService),但在一个组件中工作的东西在另一个组件中不起作用.根据我的理解,这里检查的内容的"真实性"应该足以回复真实的陈述.
但是在次要的,不相关的组件中,当我调用函数时,我得到一个"未定义"错误,如下所示:
isRoomRoute() { if (this.routeService.isRoomRoute(this.routeUrl)) { return true; } }
所以这就是我被困住的地方.基本上,关于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); } }); } }
当涉及到服务时,我们将在此处介绍BehaviorSubject
作为委托,因此使用该服务的组件可以订阅服务数据更改.有关BehaviorSubject
其他主题的更多信息,请访问:委托:Angular2中的EventEmitter或Observable
以下是我们共享的实现RouteService
(组件需要使用服务的单个实例,因此请确保您已在根级别提供它):
@Injectable() export class RouteService { isRoomRouteSource: BehaviorSubject= 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'); } }
使用该服务的另一个组件的示例,并订阅我们的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); }); } }
如果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); } }
希望这有帮助!