【问题标题】:Angular 2 - NgFor not updating viewAngular 2 - NgFor 不更新视图
【发布时间】:2018-08-29 00:42:11
【问题描述】:

我正在处理 angular 2 项目,但在尝试更改列表时遇到了问题。 NgFor 无法识别更改,仅显示第一次加载的列表。

这是一个示例代码,当我加载所有列表时,加载后我马上用 null 重置它。视图仍然显示所有列表...

这是我的组件构造函数,例如:

 constructor( private songService : SongService)
    this.songService.getSongs()
         .subscribe(songsList => {
             this.songs = songsList;
         });

    this.songs = null;

}

这是html:

<div class="row">
    <div  *ngFor= "let song of songs" class="col-md-4">
     <app-song-item [song]="song"></app-song-item>
    <br>
    </div>
</div>

【问题讨论】:

  • 请发布您的整个代码,而不是示例。如果您想发布示例,请制作 MCVE。
  • 您正在尝试显示尚不存在的数据
  • @tricheriche 这是所有代码
  • 您想在 UI 中显示“songsList”吗?或者你不想?你是说,“我正在加载所有列表,加载后我马上用 null 重置它。视图仍然显示所有列表”。
  • 在 this.songs = songList(订阅内)和 this.songs = null 处设置断点,以查看歌曲列表的更改顺序。将列表重置为 null 后可能会调用订阅回调。

标签: javascript angular components ngfor


【解决方案1】:

Angular 中的循环有时会搞砸,因为它们不会按照您希望的方式跟踪您的项目。

为了防止这种情况,您可以像这样使用自定义跟踪功能

<div *ngFor="let song of songs; let i = index; trackBy: customTB" class="col-md-4">

在你的 TS 中

customTB(index, song) { return `${index}-${song.id}`; }

这样,您设置了一个自定义 trackBy 函数,该函数将更新您的视图(视图未更新,因为跟踪 ID 未更改)。

【讨论】:

    【解决方案2】:

    您仍然看到您的列表的原因是因为它是异步的。您无法确定 subscribe 方法何时执行。它可以是直接的,在几秒钟内,需要几个小时甚至根本不需要。因此,在您的情况下,您甚至在获得列表之前就重置了列表。

    constructor( private songService : SongService)
      this.songService.getSongs()
        .subscribe(songsList => { //Might take a while before executed.
          this.songs = songsList;
        });
    
      this.songs = null; //executed directly
    }
    

    上述解释可能是您的问题的原因,但也可能有其他解释。只有在创建组件时才会调用构造函数。更改路由器参数不一定会创建组件。如果可以,Angular 可能会重用该组件。

    【讨论】:

    • 谢谢你我明白你在说什么,我也尝试用可变类型的数字来做。在构造函数 number = 5 上,在其他函数上我将其更改为 6 ,控制台显示该数字现在是 6 但视图没有变化。当然在 html 中我绑定了数字 {{number}}
    • 也许您可以创建一个工作示例来展示您的问题。
    【解决方案3】:

    你应该设置一个空数组,而不是 null ,并将它放在一个方法中,否则它永远不会被调用

     this.songService.getSongs()
             .subscribe(songsList => {
                 this.songs = songsList;
             });
    clear(){
        this.songs = [];
    }
    

    【讨论】:

    • 谢谢你,但它没有解决问题,仍然显示所有列表
    • 你必须从模板中调用方法
    【解决方案4】:

    试试这个

    constructor(private songService: SongService) {
        this.songService.getSongs()
            .subscribe(songsList => {
                this.songs = songsList;
                this.reset();
            });
    }
    
    reset() {
        this.songs = [];
    }
    

    【讨论】:

    • 这是 wokring ,但在任何其他地方我都试图这样做它不起作用。正如我在其他帖子中评论的那样,我也尝试使用初始化为 5 的数字并将其绑定到 html 代码中,在其他函数中我增加了数字但视图无法识别更改
    猜你喜欢
    • 2020-01-30
    • 2016-10-10
    • 1970-01-01
    • 2019-01-26
    • 2016-06-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-03
    相关资源
    最近更新 更多