Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript Angular2刷新阵列推送上的视图_Javascript_Arrays_Asynchronous_Angular_Setinterval - Fatal编程技术网

Javascript Angular2刷新阵列推送上的视图

Javascript Angular2刷新阵列推送上的视图,javascript,arrays,asynchronous,angular,setinterval,Javascript,Arrays,Asynchronous,Angular,Setinterval,我似乎无法在从setInterval异步操作调用的array.push函数上更新angular2视图 代码来源于: 我想做的是: 从'angular2/angular2'导入{视图、组件、引导、指令、ChangeDetectionStrategy、ChangeDetectorRef} @组件({选择器:'cmp',changeDetection:ChangeDetectionStrategy.OnPush}) @视图({template:`Number of ticks:{{{numberOf

我似乎无法在从setInterval异步操作调用的array.push函数上更新angular2视图

代码来源于:

我想做的是:

从'angular2/angular2'导入{视图、组件、引导、指令、ChangeDetectionStrategy、ChangeDetectorRef}
@组件({选择器:'cmp',changeDetection:ChangeDetectionStrategy.OnPush})
@视图({template:`Number of ticks:{{{numberOfTicks}}}`})
类Cmp{
numberOfTicks=[];
构造函数(私有引用:ChangeDetectorRef){
设置间隔(()=>{
这个.numberOfTicks.push(3);
此.ref.markForCheck()为;
}, 1000);
}
}
@组成部分({
选择器:“应用程序”,
changeDetection:ChangeDetectionStrategy.OnPush
})
@看法({
模板:`
`,
指令:[Cmp]
})
类应用程序{
}
引导(App)

安圭拉2游乐场
System.import('app')
.catch(console.error.bind(console));

在数组中添加元素后,需要更新数组的整个引用:

  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))
    }
  }
}
@组件({
选择器:“自定义检查”,
模板:`
    {{line}
` }) 类CustomCheckComponent实现DoCheck{ @Input()列表:任意[]; 不同:任何; 日志=[]; 构造函数(不同:IterableDiffers){ this.difference=differences.find([]).create(null); } ngDoCheck(){ var changes=this.difference.diff(this.list); 如果(更改){ changes.forEachAddedItem(r=>this.logs.push('added'+r.item)); changes.forEachRemovedItem(r=>this.logs.push('removed'+r.item)) } } }
如果“numberOfTicks”只是一个数字,上面的代码将正常工作,但一旦我将其更改为数组并推送数据,它将不会更新。我似乎不明白这是为什么

这是因为数字是JavaScript基元类型,数组是JavaScript引用类型。当角度变化检测运行时,它使用
==
确定模板绑定是否发生了变化

如果
{{numberOfTicks}}
是基元类型,
==
比较当前值和以前的值。因此
0
1
的值是不同的

如果
{{numberOfTicks}}
是引用类型,
==
比较当前值和以前的(引用)值。因此,如果数组引用没有更改,Angular将不会检测到更改。在您的情况下,使用
push()
,数组引用不会更改

如果您将以下内容放在模板中

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

好的,如果每个项目都是基本类型,它将更新。

谢谢Thierry,虽然这确实解决了我在这里描述的问题,但我将进一步阐述。我试图通过更新一个图的值数组来动态地更新它,事实是,如果我对数组进行切片,图将被完全重新绘制。在angular 1.x中,我使用$timeout/$interval来执行此操作,它运行$apply并使angular检测更改。我正在尝试使用angular 2I实现同样的“实时”效果,我将重新措辞-使用您在图形中建议的方法将起作用,只有图形会“闪烁”,而不是仅在现有图形上绘制一个新点,我理解。也许您可以在组件中注入ChangeDetectorRef实例,并在数组中添加元素后调用其markForCheck方法。是的,这正是我要做的,不幸的是,angular似乎仍然需要更改数组引用。然而,我看到的行为非常奇怪。如果我在浏览器上执行任何操作,Angular将更新图形。例如调整浏览器大小/打开和关闭调试器。只要我这样做,图形就会以与angular 1中相同的行为神奇地更新。@ThierryTemplier==>404&&===>404我将详细说明-我正试图通过使用上述setInterval方法更新图形的数据数组来实时更新图形,这个plunker可能是一个很好的例子来尝试实现这一点:这似乎不再有效,我得到了“意外的标记”错误。尽管angular2似乎不再真正使用===了,因为推到数组就可以了。我猜他们会进行完整的对象比较,包括遍历数组。
<span *ngFor="#item of from">{{item}}</span>
<span *ngFor="#item of to">{{item}}</span>