簡體   English   中英

陣列推送時Angular2刷新視圖

[英]Angular2 refreshing view on array push

我似乎無法在一個array.push函數上獲得angular2視圖,該函數是從setInterval異步操作調用的。

代碼來自setInterval的這個angular plunkr示例

我想做的是如下:

 import {View, Component, bootstrap, Directive, ChangeDetectionStrategy, ChangeDetectorRef} from 'angular2/angular2' @Component({selector: 'cmp', changeDetection: ChangeDetectionStrategy.OnPush}) @View({template: `Number of ticks: {{numberOfTicks}}`}) class Cmp { numberOfTicks = []; constructor(private ref: ChangeDetectorRef) { setInterval(() => { this.numberOfTicks.push(3); this.ref.markForCheck(); }, 1000); } } @Component({ selector: 'app', changeDetection: ChangeDetectionStrategy.OnPush }) @View({ template: ` <cmp><cmp> `, directives: [Cmp] }) class App { } bootstrap(App); 
 <!DOCTYPE html> <html> <head> <title>angular2 playground</title> <script src="https://code.angularjs.org/tools/traceur-runtime.js"></script> <script src="https://code.angularjs.org/tools/system.js"></script> <script src="https://code.angularjs.org/tools/typescript.js"></script> <script data-require="jasmine" data-semver="2.2.1" src="http://cdnjs.cloudflare.com/ajax/libs/jasmine/2.2.1/jasmine.js"></script> <script data-require="jasmine" data-semver="2.2.1" src="http://cdnjs.cloudflare.com/ajax/libs/jasmine/2.2.1/jasmine-html.js"></script> <script data-require="jasmine@*" data-semver="2.2.1" src="http://cdnjs.cloudflare.com/ajax/libs/jasmine/2.2.1/boot.js"></script> <script src="config.js"></script> <script src="https://code.angularjs.org/2.0.0-alpha.37/angular2.min.js"></script> <script> System.import('app') .catch(console.error.bind(console)); </script> </head> <body> <app></app> </body> </html> 

如果“numberOfTicks”只是一個數字(如plunker原始示例所示),上面的代碼將正常工作,但一旦我將其更改為數組並推送數據,它將不會更新。

我似乎無法理解為什么會這樣。

以下行為類似於我在使用setInterval / setTimeout嘗試使用新數據點更新angular2中的圖形時遇到的問題。

謝謝您的幫助。

在添加元素后,您需要更新數組的整個引用:

  constructor(private ref: ChangeDetectorRef) {
    setInterval(() => {
      this.numberOfTicks.push(3);
      this.numberOfTicks = this.numberOfTicks.slice();
      this.ref.markForCheck();
    }, 1000);
  }
}

編輯

DoCheck界面也可能讓您感興趣,因為它允許您插入自己的變化檢測算法。

有關詳細信息,請參閱此鏈接:

這是一個示例:

@Component({
  selector: 'custom-check',
  template: `
    <ul>
      <li *ngFor="#line of logs">{{line}}</li>
    </ul>`
})
class CustomCheckComponent implements DoCheck {
  @Input() list: any[];
  differ: any;
  logs = [];

  constructor(differs: IterableDiffers) {
    this.differ = differs.find([]).create(null);
  }

  ngDoCheck() {
    var changes = this.differ.diff(this.list);
    if (changes) {
      changes.forEachAddedItem(r => this.logs.push('added ' + r.item));
      changes.forEachRemovedItem(r => this.logs.push('removed ' + r.item))
    }
  }
}

如果“numberOfTicks”只是一個數字,上面的代碼將正常工作,但一旦我將其更改為數組並推送數據,它將不會更新。 我似乎無法理解為什么會這樣。

這是因為數字是JavaScript基元類型,而數組是JavaScript引用類型。 當角度變化檢測運行時,它使用===來確定模板綁定是否已更改。

如果{{numberOfTicks}}是基本類型,則===比較當前值和先前值。 所以值01是不同的。

如果{{numberOfTicks}}是引用類型,則===比較當前和之前(引用)值。 因此,如果數組引用沒有改變,Angular將不會檢測到更改。 在您的情況下,使用push() ,數組引用不會更改。

如果您將以下內容放在模板中

<div *ngFor="#tick of numberOfTicks">{{tick}}</div>

然后Angular會更新視圖,因為有一個綁定到每個數組元素,而不僅僅是數組本身。 因此,如果新項目是push() ed,或者現有項目被刪除或更改,則將檢測到所有這些更改。

因此,在您的圖表plunker中,當fromto數組的內容發生更改時,以下內容應該更新:

<span *ngFor="#item of from">{{item}}</span>
<span *ngFor="#item of to">{{item}}</span>

好吧,如果每個項目都是基本類型,它將更新。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM