Javascript Angular2刷新阵列推送上的视图
我似乎无法在从setInterval异步操作调用的array.push函数上更新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
从'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>