Angular 不会更新数组推送的视图

Posted

技术标签:

【中文标题】Angular 不会更新数组推送的视图【英文标题】:Angular doesn't update view on array push 【发布时间】:2021-06-29 11:33:34 【问题描述】:

我对使用离子无限滚动组件加载帖子的函数有疑问。 该函数在其他组件上运行良好,但在这个组件中,当我将新帖子推送到数组中时,视图不会更新。

这是不起作用的功能:

 // handles infinite scroll
  // loads more posts when getting to the bottom of the page
  async loadMorePosts(event): Promise<void> 

    await this.postService.getUserPosts(this.userId, this.offset).toPromise().then((posts: Posts) => 
      posts.rows.forEach((post: Post) => 
        this.posts.push(post)
      )
    )

    event.target.complete()
    // increments offset for the next query
    this.offset += this.offset

    //  if all data is loaded, disables infinite scroll
    if (this.posts.length == this.totalPosts) 
      event.target.disabled = true;
    
  

这是一个有效的方法:

 // handles infinite scroll
  // loads more posts when getting to the bottom of the page
  async loadMorePosts(event): Promise<void> 

    await this.postService.getOwnPosts(this.offset).toPromise().then((posts: Posts) => 
      return posts.rows.forEach((post: Post) => 
        this.posts.rows.push(post)
      )
    )
    
    event.target.complete()
    // increments offset for the next query
    this.offset += this.posts.offset

    //  if all data is loaded, disables infinite scroll
    if (this.posts.rows.length == this.totalPosts) 
      event.target.disabled = true;
    
  

这里是html

<ion-content>
  <ion-refresher slot="fixed" (ionRefresh)="doRefresh($event)">
    <ion-refresher-content></ion-refresher-content>
  </ion-refresher>
  <ion-grid id="profile" class="ion-no-padding">
    <ion-row class="ion-justify-content-center">
      <ion-col class="profile" size="10">
        <div>
          <ion-avatar class="profile__avatar">
            <ion-img src="/assets/img/profile_img.jpeg"></ion-img>
          </ion-avatar>
        </div>
        <div class="profile__gym">
          <div class="profile__gym-location">
            <ion-icon name="location-sharp"></ion-icon>
            <p>profile?.gym</p>
          </div>
          <div class="profile__gym-sport">
            <ion-img src="/assets//img/male_flexin.png"></ion-img>
            <p>profile?.discipline</p>
          </div>

        </div>
      </ion-col>
    </ion-row>

    <ion-row class="ion-justify-content-center">
      <ion-col size="9">
        <div class="description">
          <p>profile?.bio</p>
        </div>
      </ion-col>
    </ion-row>

    <ion-row class="ion-justify-content-evenly buttons">
      <ion-col size="4">
        <ion-button (click)="follow()" mode="ios" expand="block">
          profile?.isFollowing ? "Abonné(e)" : "S'abonner" 
        </ion-button>
      </ion-col>
      <ion-col size="4">
        <ion-button (click)="navigateToDirectMessages()" mode="ios" expand="block">
          Écrire
        </ion-button>
      </ion-col>
    </ion-row>

    <ion-row class="ion-justify-content-center">
      <ion-col size="10">

        <div (click)="navigateToFollowers(profile?.user_id)" class="follow-count">
          <div class="follow-count--flex-column txt-center">
            <p>totalPosts</p>
            <p class="follow-count__txt">Posts</p>
          </div>
          <div class="follow-count--flex-column txt-center">
            <p>following?.count</p>
            <p class="follow-count__txt">Abonnements</p>
          </div>
          <div class="follow-count--flex-column txt-center">
            <p>followers?.count</p>
            <p class="follow-count__txt">Abonnés</p>
          </div>
        </div>

      </ion-col>
    </ion-row>

    <ion-row class="ion-justify-content-center ion-margin-bottom">
      <ion-col size="10">

        <div class="sections">
          <div (click)="setSection(0)" class="sections__gallery">
            <p>Gallerie</p>
            <ion-icon *ngIf="indexSection == 0" name="ellipse"></ion-icon>
          </div>

          <div (click)="setSection(1)" class="sections__routine">
            <p>Programmes</p>
            <ion-icon *ngIf="indexSection == 1" name="ellipse"></ion-icon>
          </div>

          <div (click)="setSection(2)" class="sections__nutrition">
            <p>Diète</p>
            <ion-icon *ngIf="indexSection == 2" name="ellipse"></ion-icon>
          </div>
        </div>

      </ion-col>
    </ion-row>

    <ion-row class="card-row">
      <ion-col>
        <ion-card class="card">
          <ion-slides [options]="sliderOpts" #slides (ionSlideDidChange)="slideToSection()">
            <ion-slide>
              <div class="gallery">
                <div class="gallery__img" *ngFor="let post of posts ; let i = index">
                  <ion-img (click)="openLightbox(i)" [src]="imgUrl+post?.img"></ion-img>
                </div>
                <div *ngIf="!posts" class="gallery__placeholder">
                  <ion-label>Cette section est vide</ion-label>
                </div>

              </div>
            </ion-slide>

            <ion-slide>
              <div class="program">
                <ion-card *ngFor="let program of profile?.programs ; let i = index">
                  <ion-item (click)="navigateToProgram(program?.id)" detail lines="none">
                    <ion-label>
                      <h5>
                        setDay(program?.day)
                      </h5>
                    </ion-label>
                  </ion-item>
                  <ion-item lines="none">
                    <ion-icon slot="start" size="small" name="time-outline"></ion-icon>
                    <ion-label>
                      program?.duration</ion-label>
                  </ion-item>
                </ion-card>
                <div *ngIf="profile?.programs?.length == 0" class="program__placeholder">
                  <ion-label>Cette section est vide</ion-label>
                </div>
              </div>

            </ion-slide>

            <ion-slide>
              <div class="nutrition">
                <ion-card (click)="navigateToMeal(meal?.id)" *ngFor="let meal of profile?.meals">
                  <ion-item class="nutrition__meal" detail lines="none">
                    <ion-label>
                      <h3>
                        meal?.name
                      </h3>
                      <p>meal?.time</p>
                    </ion-label>
                    <ion-label class="nutrition__meal-cal">
                      <h3>calculateTotalNutriments(meal?.meal_components,"kcal_100g") | number:'1.1-1'Kcal</h3>
                    </ion-label>
                  </ion-item>
                  <ion-item lines="none" class="nutrition__meal-macros">

                    <ion-icon class="proteins-ellipse" name="ellipse"></ion-icon>
                    <ion-label>
                      <h5>Protéines</h5>
                      <p>calculateTotalNutriments(meal?.meal_components,"proteins_100g") | number:'1.1-1'g</p>
                    </ion-label>

                    <ion-icon class="carbs-ellipse" name="ellipse"></ion-icon>
                    <ion-label>
                      <h5>Glucides</h5>
                      <p>calculateTotalNutriments(meal?.meal_components,"carbohydrates_100g") | number:'1.1-1'g</p>
                    </ion-label>
                    <ion-icon class="fat-ellipse" name="ellipse"></ion-icon>

                    <ion-label>
                      <h5>Lipides</h5>
                      <p>calculateTotalNutriments(meal?.meal_components,"fat_100g") | number:'1.1-1'g</p>
                    </ion-label>

                  </ion-item>
                </ion-card>
                <div *ngIf="profile?.meals?.length == 0" class="nutrition__placeholder">
                  <ion-label>Cette section est vide</ion-label>
                </div>
              </div>

            </ion-slide>

          </ion-slides>
        </ion-card>
      </ion-col>
    </ion-row>

  </ion-grid>

  <app-lightbox id="lightbox" class="lightbox" [totalPosts]="totalPosts" [postIndex]="postIndex" [posts]="posts">
  </app-lightbox>
  <ion-infinite-scroll (ionInfinite)="loadMorePosts($event)">
    <ion-infinite-scroll-content loadingSpinner="crescent">
    </ion-infinite-scroll-content>
  </ion-infinite-scroll>
</ion-content>

我是新手,所以如果缺少某些信息或我的请求格式不正确,请随时说出来。

感谢您的帮助

【问题讨论】:

你怎么知道它的工作原理,你在控制台中得到了想要的值吗? 是的,当我记录我的数组时,我可以看到它的长度增加了,但角度变化检测没有更新视图。在其他组件中,当我将新项目推送到数组中时,视图会更新。 【参考方案1】:

我的问题已经解决了。触发变更检测时卡边距和溢出冲突,新帖子隐藏在下面。

【讨论】:

【参考方案2】:

您缺少 return 关键字。

await this.postService.getUserPosts(this.userId, this.offset).toPromise().then((posts: Posts) => 
  return posts.rows.forEach((post: Post) => 
    this.posts.push(post)
  )
)

【讨论】:

以上是关于Angular 不会更新数组推送的视图的主要内容,如果未能解决你的问题,请参考以下文章

Angular 2 在 ngOnInit 承诺中推送数组后不刷新视图

为啥 Angular 2 ngOnChanges 不响应输入数组推送

推送视图:在发生现有转换或演示时;导航堆栈不会更新

Angular 8 值在更改后不会在视图上更新

Angular - 我的控制器不会在视图中更新我的组件数据

Swiftui 列表更新问题