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 承诺中推送数组后不刷新视图的主要内容,如果未能解决你的问题,请参考以下文章

在 ngOnInit Angular 之前处理异步承诺

如何在 Angular 4 中推送到数组的 Observable? RxJS

如何重定向到 ngOnInit 中的新组件

异步 ngOnInit

Angular2 - 在组件中测试 ngOninit

Angular 2 应用程序中 NgOnInit 生命周期钩子中移动方法的问题