16

我创建了一个具有 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

4

3 回答 3

25

更改检测基于引用,将元素推送到数组不会触发它。尝试像这样更新参考:

this.stories.push(story);
this.stories = this.stories.slice();
于 2016-08-29T08:30:27.123 回答
0
        setTimeout(function () {
            this.stories.push(story);
        }, 0);

我在推入嵌套数组时遇到了麻烦,几乎是随机刷新结果,直到我难倒了这个规范:

基本上应用程序状态的变化可能是由三件事引起的:

  • 事件 - 点击、提交……</p>

  • XHR - 从远程服务器获取数据

  • 定时器 - setTimeout(), setInterval()

https://blog.thoughtram.io/angular/2016/02/22/angular-2-change-detection-explained.html#what-c​​auses -change )

所以我尝试了setTimeout,奇迹般地奏效了......

于 2018-04-18T20:45:33.693 回答
0

我认为解决这个问题的最好方法是在*ngFor指令中添加(trackBy:trackByFn)

<Label *ngFor="let story of stories; trackBy:trackByFn" [text]='story.message'></Label>

并在 Typescript 中添加trackByFn类组件中的方法:

trackByFn(index: any, item: any) {
    return index;
}
于 2021-04-15T15:33:57.177 回答