【问题标题】:Angular 2 not detecting changes in service variable from componentAngular 2 未检测到组件中服务变量的变化
【发布时间】:2018-09-06 14:30:08
【问题描述】:

下午好,

我正在尝试更新我的组件以在服务变量更改时显示正确的值。我目前有这个:

组件1 HTML

{{icons | json}}

组件1

icons: {
  icon1: boolean,
  icon2: boolean,
}

constructor(private _service: Service1) {
  this.icons = this._service.navIcons;
}

组件2

constructor(private _service: Service1) {
  this._service.signIn();
}

服务1

navIcons: {
  icon1: false,
  icon2: false
}

navIconsChange: Subject<any> = new Subject<any>();

constructor() { 
  this.navIconsChange.subscribe((value) => { this.navIcons = value; console.log(value) });
}

resetIcons() {
  this.navIconsChange.next(
    this.navIcons = {
       icon1: false,
       icon2: false
    });
}

signIn() {
  this.navIconsChange.next(
    this.navIcons = {
       icon1: true,
       icon2: true
    });
}

这个想法是,当从 Component2 调用 signIn() 方法时,navIcons 应该更新并且这些更新应该显示在 Component1 上。我在订阅日志中的console.log 发生了此更改,但是,Component1 HTML 中的图标永远不会更新。我会假设这些应该自动更新,因为图标正在从 Service1 的 Component1 的构造函数中更新。当 Component2 调用 signIn() 方法时,如何让这些变量更新?

这一切都基于这个答案:https://stackoverflow.com/a/43161506/4927000

谢谢!

【问题讨论】:

    标签: angular typescript rxjs observable


    【解决方案1】:

    您需要修改大部分代码,因为您做错了很多事情。

    组件 1

    icons: {
      icon1: boolean,
      icon2: boolean,
    }
    
    constructor(private _service: Service1) {
        this._service.navIconsChange.subscribe((value) => {
         this.navIcons = value; 
         console.log(value) 
        });
    }
    

    服务 1

    navIcons: {
      icon1: false,
      icon2: false
    }
    
    navIconsChange: Subject<any> = new Subject<any>();
    
    resetIcons() {
      this.navIconsChange.next({
           icon1: false,
           icon2: false
        });
    }
    
    signIn() {
      this.navIconsChange.next({
           icon1: true,
           icon2: true
        });
    }
    

    Component 2 和 Component1 HTML 将保持不变。

    这样您的comopnent 1 就会知道值何时发生变化。

    此外,如果您想将结果缓存在其他组件的服务中,您可以在.next 之后手动将其分配给变量或使用BehaviourSubject,例如:

    服务 1

    navIcons = {
      icon1: false,
      icon2: false
    }
    
    navIconsChange: Subject<any> = new BehaviourSubject<any>(navIcons);
    

    如果您需要进一步帮助,请添加 cmets。

    【讨论】:

    • 这似乎在正确的轨道上,但是订阅似乎需要一段时间才能执行。另外,我收到以下错误: ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it is checked。以前的值:'ngIf: true'。当前值:'ngIf: false'。我之前直接从 HTML 调用服务时遇到了这个错误,所以我想更改它。关于为什么会发生这种情况的任何想法?
    • 我通过向订阅添加 setTimeout() 函数来消除错误,如以下答案所示:stackoverflow.com/a/45444242/4927000。一切都在快速运行,正如我所期望的那样,但我不禁认为这是一种糟糕的执行方式。想法?
    • 没关系,我意识到我在 ngOnInit() 中更改了这些值,而不是构造函数,所以听起来这些更改是在更改检测发生之前进行的。非常感谢您的帮助!
    • @Josh 我希望你一切都好。但是不要在你的代码中使用setTimeout 可能你可以发布完整的错误或代码来帮助理解这个问题。 @acdcjunior 看到您如此出色的学习态度并积极接受反馈,我感到非常惊讶。我也会尝试复制它。 :D
    • 是的,不使用 setTimeout 一切正常。我有一种感觉,这不是一个很好的选择。 :) 再次感谢您的帮助,我能够通过将代码移动到构造函数而不是 ngOnInit 来修复 ExpressionChangedAfterItHasBeenCheckedError。
    猜你喜欢
    • 2018-06-14
    • 2018-07-10
    • 2017-06-04
    • 1970-01-01
    • 2016-07-15
    • 2017-06-07
    • 2019-06-09
    • 2017-01-01
    • 2018-05-14
    相关资源
    最近更新 更多