【问题标题】:Why does this method/gettor get called X times in an Angular 2 service为什么这个方法/gettor 在 Angular 2 服务中被调用 X 次
【发布时间】:2016-11-25 18:40:42
【问题描述】:

我正在尝试将我的 HTML 组件中的值绑定到服务中的属性。如果私有变量为空,那么它需要关闭并从 HTTP 调用中获取值。

但是,我注意到,一旦我绑定到 HTML 组件中的属性 gettor,它就会触发多次。

我已将示例简化为: this Plunker

  get Item(): string {
      console.log("Item()", this._item);
      return this._item;
  }

打开控制台,观察“Item() Initiated”的多个输出。我希望它只会被击中一次。 (结果与方法而不是 gettor 相同)。如果我在点击方法中使用 Gettor,它只会触发一次。

【问题讨论】:

  • 因为Angular需要在每个变化检测周期调用该方法来知道返回值是否发生变化,从而相应地更新DOM。
  • 谢谢,我明白了。因此,如果我要启动并点击 HTTP 服务来更新值,我想我需要检查它是否已经在进行中(或者它会多次启动逻辑)。
  • 没有。你不需要做任何这些。它不能进行,因为 JS 在单线程中运行。因此,如果该线程正在处理您的 HTTP 回调,它就不能同时处理更改检测。

标签: angular angular2-template


【解决方案1】:

这是因为每次在应用程序中“发生变化”时,都必须评估绑定在 html 上的值,以便如果绑定项的值发生变化,它将反映到 html 中,从而给你这个神奇的自动更新绑定。这可能是 90% 的情况下您想要的,因为您不想担心通知 angular 来更新绑定属性的值。

也就是说,如果您在 getter 中有一些繁重的逻辑,或者您希望控制值何时更新,您可以将组件 changeDetectionStrategy 更改为 onPush,例如 in this plunker

@Component({
  selector: 'my-app',
  template: `
    <div><button (click)="_service.ShowItem()">Show Item</button></div>
    <div>{{_service.Item}}</div>
  `,
  providers: [ Service ],
  changeDetection: ChangeDetectionStrategy.OnPush
})

thoughtram 很好地解释了 angular2 变化检测的工作原理

这就像说,“做变更检测时不要检查这个组件,我会告诉你什么时候检查”。

然后您可以使用名为 ChangeDetectorRef 的服务来标记组件以进行更改检测。

对于 http,您想要做的是有一个触发器来执行 http 调用,然后从响应中获取您需要的值并将其“缓存”到某处,以便您可以将其绑定到 UI。根据您的情况,触发器可以是多种事物,例如。间隔、递归、按钮等

【讨论】:

  • 感谢您的详细解释-我现在正在阅读那篇文章
  • 我们可以有条件地这样做吗?
【解决方案2】:

接受的答案很棒,并且非常清楚地解释了一切。但是,就像他在 90% 的情况下所说的那样,您不会想要更改更改检测方法。因此,我有一个简单但丑陋的解决方法,我想当您访问数据库以获取一些数据并且不想连续多次访问您的 API 时,我会分享它。它将返回一个空对象,直到数据下降。确保根据需要在模板上使用 *ngIf。

private __itemHit: number = 0;
private __item: string;
get Item(): string {
    if(!this.__item && this.__itemHit == 0){
        this.__itemHit = 1;

        //Your data fetch is likely different than the way I do mine.
        apiService.Post(url, body, option).subscribe((response) => { this.__item = response.Result;});
        console.log("Item()", this._item);
    }
    return this._item;
}

【讨论】:

  • 我这样做是为了快速解决问题,但发现组件树上的其他 getter 和 setter 很有可能做同样的事情。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-05
  • 2019-08-05
  • 2016-06-03
  • 1970-01-01
  • 2012-09-26
相关资源
最近更新 更多