为什么在Angular 2服务中调用此方法/ gettor X次

时间:2016-11-25 18:40:43

标签: angular angular2-template

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

然而,我注意到,只要我绑定到HTML组件中的属性gettor,它就会多次触发。

我简化了以下示例: this Plunker

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

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

2 个答案:

答案 0 :(得分:16)

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

如果您在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。根据您的情况,触发器可以是各种各样的东西,例如。间隔,递归,按钮等

答案 1 :(得分:1)

接受的答案非常棒,并且非常清楚地解释了一切。但是,正如他90%的时间所说,你不会想要改变变化检测方法。所以我有一个简单的,尽管是丑陋的解决方案,我认为当你去数据库获取一些数据并且不想连续多次点击你的API时我会分享。它将返回一个null对象,直到数据结束。确保根据需要在模板上使用* 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;
}