Angular 2 在 ngOnInit 承诺中推送数组后不刷新视图
Posted
技术标签:
【中文标题】Angular 2 在 ngOnInit 承诺中推送数组后不刷新视图【英文标题】:Angular 2 do not refresh view after array push in ngOnInit promise 【发布时间】:2017-01-04 22:11:54 【问题描述】:我创建了一个 Angular 2 的 NativeScript 应用程序,我有一个我希望在应用程序前端看到的对象数组。行为是,如果我将一个对象直接推入 ngOnInit() 内部的数组中,它会起作用,但如果我在 ngOnInit() 中创建一个承诺,它就不起作用。这是代码:
export class DashboardComponent
stories: Story[] = [];
pushArray()
let story:Story = new Story(1,1,"ASD", "pushed");
this.stories.push(story);
ngOnInit()
this.pushArray(); //this is shown
var promise = new Promise((resolve)=>
resolve(42);
console.log("promise hit");
);
promise.then(x=>
this.pushArray(); //this is NOT shown
);
相对html为:
<Label *ngFor="let story of stories" [text]='story.message'></Label>
当应用程序启动时,我只看到一个推送,但我创建了一个按钮来触发“console.log(JSON.stringify(this.stories));”在那一刻,当我点击按钮时,用户界面似乎检测到更改的数组,并出现另一个推送的对象。
编辑:
我在这个帖子中创建了一个更简单的例子:Angular 2: when i change a variable in a promise.than in ngOnInit the view doesn't refresh
【问题讨论】:
如果您重新加载页面,是否会出现更改? 【参考方案1】:变化检测基于引用,将元素推送到数组不会触发它。尝试像这样更新参考:
this.stories.push(story);
this.stories = this.stories.slice();
【讨论】:
@nickspoon 是做什么切片的 @Zammel 它创建了部分数组的副本,但是像这样不带参数地使用它只是制作整个数组的浅表副本:developer.mozilla.org/en-US/docs/Web/javascript/Reference/… 它对我不起作用。我想删除子视图,因为子视图具有列表中的输入和输出装饰器。【参考方案2】: setTimeout(function ()
this.stories.push(story);
, 0);
我在推入嵌套数组时遇到了麻烦,几乎是随机刷新结果,直到我难倒了这个规范:
基本上,应用程序状态的变化可能是由三件事引起的:
事件 - 点击、提交……
XHR - 从远程服务器获取数据
定时器 - setTimeout(), setInterval()
(https://blog.thoughtram.io/angular/2016/02/22/angular-2-change-detection-explained.html#what-causes-change)
于是我尝试了setTimeout,奇迹般地奏效了……
【讨论】:
【参考方案3】:我认为解决这个问题的最好方法是在*ngFor
指令中添加(trackBy:trackByFn)
:
<Label *ngFor="let story of stories; trackBy:trackByFn" [text]='story.message'></Label>
并在 Typescript 的类组件中添加 trackByFn
方法:
trackByFn(index: any, item: any)
return index;
【讨论】:
以上是关于Angular 2 在 ngOnInit 承诺中推送数组后不刷新视图的主要内容,如果未能解决你的问题,请参考以下文章