如何从子组件中过滤父组件中的可观察对象?

dra*_*ind 5 observable rxjs angular angular6

我有两个组件。

  1. 项目列表——用于显示项目列表(父级)
  2. Item——单个项目(子项)的包装

在 中Item List component,我基本上使用服务创建了一个可观察的对象。函数 getItems() 返回项目的可观察值:

items$: Observable<Item[]>;

ngOnInit() {
  this.items$ = this.service.getItems();
}
Run Code Online (Sandbox Code Playgroud)

在模板中,我使用异步管道执行 ngFor 来显示项目列表:

<div *ngFor="let item of items$ | async">
    <card-item [item]="item"></card-item>
</div>
Run Code Online (Sandbox Code Playgroud)

现在,Item component我可以选择从 firestore 数据库中删除该特定项目:

@Input() item: Item;

removeItem() {
    this.service.removeItem(this.item.id);
}
Run Code Online (Sandbox Code Playgroud)

此操作需要一些时间,因此我想从父组件的可观察对象中“本地”删除它。

我可能必须过滤父组件中的可观察值,并以某种方式返回一个新的过滤可观察值,但我不知道如何从子组件中管理它?

removeItem() {
    // remove from firestore, but this can take some time

    this.service.removeItem(this.item.id);

    // meanwhile... remove it from the observable on parent

    source.pipe(filter(item => item.id !== this.item.id)); // here is the problem I have
}
Run Code Online (Sandbox Code Playgroud)

正如您在上面看到的,我不知道如何“连接”到可观察对象并过滤它。

原因是当我想要动画删除操作(如淡出)时,该项目会闪烁。这是因为动画在记录从 Firestore 中删除之前完成。

Ani*_*oui 2

我建议您将卡片项目保留为演示/哑组件。意味着您应该从中删除服务依赖性,因为它的主要工作是显示该项目。

然后,一个简单的解决方案是向卡片项添加一个输出,该输出发出删除事件,告诉其父组件“嘿!你应该删除我”。

因此,基本上在card-item.component.ts中,您的代码如下所示:

@Input() item: Item;
@Output() removeClick = new EventEmitter<Item>();

removeItem() {
    this.removeClick.emit(this.item);
}
Run Code Online (Sandbox Code Playgroud)

现在,我们来讨论从可观察部分中“删除”。我更喜欢使用术语“过滤器”,因为可观察量是流,您只需观察某个时间点的值。相反,您可以从项目数组中删除项目。在这种情况下,您需要保留当前显示的项目的本地副本。意味着删除异步管道并在组件代码中订阅您的可观察对象。

在你的item-list.component.ts中

ngOnInit() {
    this.items$ = this.service.getItems();
    this.items$.subscribe(items => {
        this.localItems = items;
    }
    )
}

onRemoveClick($event: Item) {
    // Removal logic here
    // Something like
    const index = this.localItems.indexOf($event);
    if (index > -1) {
        this.localItems.splice(index, 1);
    }
}
Run Code Online (Sandbox Code Playgroud)

在您的item-list.component.html中:

<div *ngFor="let item of localItems">
    <card-item [item]="item" (removeClick)="onRemoveClick($event)"> </card-item>
</div>
Run Code Online (Sandbox Code Playgroud)