简体   繁体   中英

Ionic2 ngFor in view not updating

I have list of elements in my app, printing them out within *ngFor. When the app is resumed I call a method to load new elements from the server by doing a http-Request. Inside this method I set the items as elements of the array.

However the array is not updated in the view. If i do a pull-to-refresh (on which I call the same method) the elements in the view are updated.

I tried wrapping the part of my code, that overrides the the old array in ngZone's .run() or a setTimeout() but nothing worked. Also tried with ChangeDetectorRef , also without success.

Now i am out of any ideas...

Here is what I have tried so far:

this.zone.run(() =>{
   this.posts = posts; // "posts" is the array of elements i got from http-request
                       // "this.posts" the array for the view
});

and also

setTimeout(() => {
   this.posts = posts;
}, 10);

and

this.posts = posts;
this.changedetectorRef.detectChanges(); //also tried markForCheck()

MY CODE:

view:

<ion-item-sliding *ngFor="let post of posts" >
    <ion-item>
        <p>{{post.newdistance}}</p>
    </ion-item>
</ion-item-sliding>

corresponding .ts file:

loadPosts() {
  let loading = this.loadingController.create({
    content: "Einen Moment bitte...",
    spinner: "crescent"
  });

  loading.present();

  this.postsService.getPostsFromServer().then(posts => {

    posts.forEach((post, index) => {

        this.geolocationService.getDistance(post.latitude, post.longitude).then(distance => {
            post.newdistance = distance;
        });

    });

    this.posts = posts; // <---- what to do here ???
    loading.dismiss();

  })
  .catch(() => {
    loading.dismiss();
  });
}

PLEASE help me!

UPDATE

When i put an alert and compare the old post value with the new one, both are updated. The problem is definitely the not-updating view

UPDATE 2

I noticed, when I add a button to the view on which i call the same function, the view is updated also...it just isn't updated when i resume the app...

The this.posts = posts; part of your code is executed possibly before the

this.geolocationService.getDistance(post.latitude, post.longitude).then(distance => {
            post.newdistance = distance;
        });

I say " possibly before ", because it is a promise, you cannot be sure when exactly it will return. So the newdistance value is set after you assign the posts to this.posts .

The best way to dealing with this is To chain your promise methods to be executed one after the other, not in parallel.

Another (more simple way) is to push each post into this.posts only after it has gotten the newdistance value. Keep in mind that you should use a new array to push the posts, like this:

  //at the top of you page declare a new postsArray variable
  postsArray = [];
  this.postsService.getPostsFromServer().then(posts => {

    posts.forEach((post, index) => {

        this.geolocationService.getDistance(post.latitude, post.longitude).then(distance => {
            post.newdistance = distance;
            // Here we push the new post into the posts array
            this.postsArray.push(post);
        });

    });

    loading.dismiss();

  })
  .catch(() => {
    loading.dismiss();
  });

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM