角度2 - 负载共享服务

时间:2017-08-01 17:09:28

标签: angular

我正在尝试与组件共享服务,为此,我创建了service.ts,代码如下:

import { Subject } from 'rxjs/Subject';

export class CommonService {
    CommonList = new Subject<any>();
}

当然,此服务位于app.module.ts中的提供者列表中 然后,我有一个组件侧边栏。 从侧边栏组件我订阅此服务:

  ngOnInit() {
    this.subscription = this.CommonServicePrivate.CommonList.subscribe(
      (result: any) => {
        console.log(result);
      }
    );
  }

这是问题,如果我尝试通过某种方法从app.component.ts添加此服务中的一些列表:

  click(){
   this.CommonService.CommonList.next([{"some_key":"some_value"}]);
  }

这实际上有效,但是当我尝试这个时:

  ngOnInit(){
    this.CommonService.CommonList.next([{"some_key":"some_value"}]); 
  }

它不起作用。

关键是我想将此服务传递给加载应用程序中的组件。

在ngAfterViewInit的情况下,当我尝试将此结果呈现给某个模板时,我收到错误: ExpressionChangedAfterItHasBeenCheckedError:表达式在检查后发生了变化。上一个值:'undefined'。当前价值:

如果有人有此经验,请与我分享。 感谢。

2 个答案:

答案 0 :(得分:0)

主体在订阅时会为其订阅增值。当你从CommonList推进ngOnInit内部的价值时,它会发出价值。但是潜在的内部组件(事件订阅)还没有发生。

您可以通过使用ngAfterViewInit生命周期钩子来解决此问题,它可以确保内部组件树已初始化(期望内容投影)。从本质上讲,它将确保组件subscription已经发生。

ngAfterViewInit(){
  this.CommonService.CommonList.next([{"some_key":"some_value"}]); 
}

或者实现相同目标的另一种方法是,BehaviourSubject使用Subject。这两者之间的差异是BehaviourSubject存储&amp;发出最后一次订阅。

答案 1 :(得分:0)

我可以建议解决ExpressionChangedAfterItHasBeenCheckedError

这是枪手在https://stackoverflow.com/a/43375600/2708210

指出的真正错误

你可以做的是在setTimeout内部进行调用我有这个问题,这是一个解决方法。

 this.subscription = this.service.spinner$
  .subscribe(item => setTimeout(() => this.showProgress = item, 0)); 
  

这是我的应用git link

的代码