如何防止在ngFor指令

时间:2017-08-29 13:49:39

标签: angular

我是否可以在ngFor指令中包含组件,这样一来,当数据发生变化时,不必每次调用组件的构造函数?

Plunker示例:http://plnkr.co/edit/6A6Aj8yeFqNd28Nl8cyS?p=preview

我只想更新数据,而不是重新创建组件。打开控制台,看看我的意思更好。

AppComponent:

@Component({
  selector: 'my-app',
  template: `
    <div>
      <div *ngFor="let value of sourceData">
        <fizz [sampleInputValue]="value"></fizz>
      </div>
    </div>
  `,
})
export class App {

  sourceData: number[] = [];

  ngOnInit() {
    setInterval(() => {
      let newArrayOfRandomNumbers: number[] = [
        Math.floor(Math.random() * 60) + 1,
        Math.floor(Math.random() * 60) + 1,
        Math.floor(Math.random() * 60) + 1,
        Math.floor(Math.random() * 60) + 1,
        Math.floor(Math.random() * 60) + 1
      ]

      newArrayOfRandomNumbers.forEach((randomNumber, index) => {
        this.sourceData[index]= newArrayOfRandomNumbers[index];
      });
    }, 500);
  }
}

FizzComponent:

@Component({
  selector: 'fizz',
  template: `
    {{sampleInputValue}}  
  `
})
export class FizzComponent {

  @Input()sampleInputValue: number;

  constructor() {
    console.log("I dont want to be called, I just want the data to be updated")
  }
}

2 个答案:

答案 0 :(得分:1)

问题是Angular使用默认的trackBy函数,该函数按身份进行比较。如果不匹配,它会重新创建组件并因此调用它的构造函数。

您可以利用它并将值作为具有数字属性的对象传递给ngFor

  sourceData = [{},{},{},{},{}];

  ngOnInit() {
    setInterval(() => {
      let newArrayOfRandomNumbers: number[] = [
        Math.floor(Math.random() * 60) + 1,
        Math.floor(Math.random() * 60) + 1,
        Math.floor(Math.random() * 60) + 1,
        Math.floor(Math.random() * 60) + 1,
        Math.floor(Math.random() * 60) + 1
      ]

      newArrayOfRandomNumbers.forEach((randomNumber, index) => {
        this.sourceData[index].v= newArrayOfRandomNumbers[index];
      });
    }, 500);

这不会重新创建组件。请参阅this plunker

另请参阅this answer以了解有关ngFor trackBy的更多信息。

答案 1 :(得分:0)

不,那是不可能的。

每次渲染组件时,都会创建一个新实例。如果您只想执行一次逻辑,请将其从构造函数移动到服务。