如何更新子模型而不重置整个视图?

时间:2018-09-12 09:42:58

标签: angular

我对棱角还很陌生,我只是找不到以下问题的例子:

假设您有一个仅显示items列表的组件。每个item从父ItemsComponent传递到子ItemComponent组件。经典示例。

但是,我们还假设只要有更改,我们就希望更新items的列表。因此,我们每5秒钟进行一次讨厌的民意调查(欢迎提出更好的解决方案的建议)。这样将更新items并销毁每个ItemComponent子代,以创建新的子代。

@Component({
  selector: 'app-items',
  templateUrl: './items.component.html',
  styleUrls: ['./items.component.css'],
  template:`
    <div *ngFor="let item of items">
      <app-item [item]="item"></app-item>
    <div>
  `
})
export class ItemsComponent implements OnInit {

  private polling;

  public items: Array<ItemModel>;

  constructor(private itemsService: ItemsService) {}

  ngOnInit() {
    this.polling = interval(5000).pipe(
       startWith(0),
       map(() => {
         this.itemsService.getItems().subscribe(
           (items) => {this.items = items;});
        })
      ).subscribe((data) => this.processData(data));
    }
  }

  ngOnDestroy() {
    this.polling.unsubscribe();
  }
}

现在有一些问题:

  • 用户将向后滚动(而不是向后滚动 )到顶部
  • 任何复杂状态,例如一个全屏模式的孩子也迷路了

所有这些都必须在父组件中记住并处理。

那么是否有“角”战来做到这一点,还是我必须自己在父组件中实现更新逻辑?

我最头疼的是*ngFor指令。我知道我可以使用@ViewChildren来引用那些孩子,但我无法实现我在这里寻求的目标。

那么我们如何用角度更新列表视图中的项目?

1 个答案:

答案 0 :(得分:1)

您可以使用trackBy仅重新提交更新的项目。

所有角度都是可观察的,尝试对项目数组使用asyncPipe

@Component({
  selector: 'app-items',
  templateUrl: './items.component.html',
  styleUrls: ['./items.component.css'],
  template: `
    <ng-container *ngIf="items$|async as items">
      <div *ngFor="let item of items; trackBy:item?.uniqueProp">
        <app-item [item]="item"></app-item>
      <div>
    </ng-container>
  `
})
export class ItemsComponent implements OnInit {
  public items$: Observable<Array<ItemModel>>;

  constructor(private itemsService: ItemsService) {}

  ngOnInit() {
    this.items$ = interval(5000).pipe(
      startWith(0),
      map(() => this.itemsService.getItems())
    );
  }
}