javascript - 在 Angular 2 中的非父/子关系组件之间传递值

标签 javascript angular typescript

根据我的理解,在 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 和不相关的 (room.component) 组件中都使用共享服务 (routeService),但在一个组件中有效的在另一个组件中无效。根据我的理解,这里检查的内容的“真实性”应该足以返回一个真实的陈述。

但是在次要的、不相关的组件中,当我调用该函数时出现“未定义”错误,如下所示:

  isRoomRoute() {
       if (this.routeService.isRoomRoute(this.routeUrl)) {
           return true;
       }
     }

这就是我被困的地方。基本上,关于 url 是否包含某个字符串的评估已经发生。现在我只需要将该检查的 bool 结果传递给次要的、不相关的组件。我怎样才能在 Angular 2 中最好地做到这一点?

最佳答案

您的理解是正确的,injectable 共享服务是多个不相关组件之间通信的常用方式。

以下是此类用例的演练。

首先,根据您的情况,我们会监听AppComponent中的Router事件,获取事件路由,并将其传递给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作为委托(delegate)引入,这样使用服务的组件就可以订阅服务数据的变化。有关 BehaviorSubject 和其他主题的更多信息,请访问:Delegation: EventEmitter or Observable in Angular2

这是我们共享的 RouteService 的实现(组件需要 use the single instance of the service ,因此请确保您已在根级别提供它):

@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');
    }
}

另一个组件使用该服务并订阅我们的 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);
     }

}

希望这对您有所帮助!

关于javascript - 在 Angular 2 中的非父/子关系组件之间传递值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41580262/

相关文章:

javascript - 向下滚动时隐藏导航栏并在向上滚动时显示它

javascript - 在 typescript 中返回实体数组的最简洁方法是什么?

java - JSP 向 Angular 6+ UI 提供信息

typescript - 从数字索引返回的类型必须是从字符串索引返回的类型的子类型

javascript - 为什么使用 setTimeout 可以显示图表

Angular 应用程序更新到版本 8 后无法在 Firefox 上运行

javascript - 如何首先加载动态插入的 img

javascript - 使用来自数据库的 javascript 值根据第一个更改第二个下拉值

javascript - 单击按钮后如何将具有多个类的数据属性值输入到 div?

angular - Visual Studio 2015 RC3 TypeScript Intellisense 不再工作