Javascript 从与服务共享的列表中删除元素

Javascript 从与服务共享的列表中删除元素,javascript,angular,concurrency,Javascript,Angular,Concurrency,这个问题快把我逼疯了 我在服务中定义了一个数组,该数组用于其他3个组件: 这是服务文件products.service.ts(注意产品的产品数组) 这是我订阅getProducts并填充数组(products.component.ts文件)的组件: 这是我订阅deleteProduct的组件(文件product card.component.ts): 问题是,当我点击一些删除产品按钮时,我有一种奇怪的行为: 单击之前: 单击后: 以下是products.component.html文件: &

这个问题快把我逼疯了

我在服务中定义了一个数组,该数组用于其他3个组件:

这是服务文件products.service.ts(注意产品的产品数组)

这是我订阅getProducts并填充数组(products.component.ts文件)的组件:

这是我订阅deleteProduct的组件(文件product card.component.ts):

问题是,当我点击一些删除产品按钮时,我有一种奇怪的行为:

单击之前:

单击后:

以下是products.component.html文件:

<div class="products__header">
  <h3 class="products__heading">
    Listado de productos ({{ products.length }})
  </h3>
  <input
    class="products__search"
    placeholder="Buscador"
    type="search"
    [(ngModel)]="searchText"
  />
</div>

<p *ngFor="let p of products">{{ p.name }}</p>
<p>{{ products }}</p>

<div class="products__list">
  <app-product-card
    *ngFor="let p of products | filterNames: searchText"
    [product]="p"
  ></app-product-card>
</div>

产品列表({products.length}})
{{p.name}

{{products}}

为什么在我使用产品列表的四个地方中只有两个地方出现了预期行为?


我知道当我单击按钮时,我可以使用输出手动从列表中删除该项,但我被告知,当我想在多个组件之间共享时,使用服务而不是输入/输出,因此,我不想为此使用输出,当您使用服务层上的公共数据的方法时,一个常见的陷阱是Angular无法检测到影响组件的更改。在这种情况下,您必须使用emmiter通知组件这些更改

在服务中使用emmiter

   productUpdated :EventEmitter = new EventEmitter();

 deleteProduct(p: Product) {
    // this.products = this.products.filter(prod => prod.id !== p.id);
    const i = this.products.indexOf(p);
    this.products.splice(i,1);

    this.productUpdated.emit(this.products);

    return this.http.delete(apiUrl + "/" + p.id)
  }
然后倾听更改产品组件的声音

export class ProductsComponent implements OnInit {

  products: Product[] = [];
  searchText: string = "";

  constructor(private productsService: ProductsService) {}

  ngOnInit(): void {
    this.productsService.getProducts()
      .subscribe((data: Product[]) => {
        this.productsService.products = data;
        this.products = this.productsService.products;
      })
    this.productsService.productUpdated.subscribe( (data) => { 
      this.products = data;
      });
  }

太好了,这管用了!我接受了你的答案并投了赞成票。然而,我仍然不明白为什么在我以前的代码中,一些html反映了更改,而另一些没有。
<div class="products__header">
  <h3 class="products__heading">
    Listado de productos ({{ products.length }})
  </h3>
  <input
    class="products__search"
    placeholder="Buscador"
    type="search"
    [(ngModel)]="searchText"
  />
</div>

<p *ngFor="let p of products">{{ p.name }}</p>
<p>{{ products }}</p>

<div class="products__list">
  <app-product-card
    *ngFor="let p of products | filterNames: searchText"
    [product]="p"
  ></app-product-card>
</div>
   productUpdated :EventEmitter = new EventEmitter();

 deleteProduct(p: Product) {
    // this.products = this.products.filter(prod => prod.id !== p.id);
    const i = this.products.indexOf(p);
    this.products.splice(i,1);

    this.productUpdated.emit(this.products);

    return this.http.delete(apiUrl + "/" + p.id)
  }
export class ProductsComponent implements OnInit {

  products: Product[] = [];
  searchText: string = "";

  constructor(private productsService: ProductsService) {}

  ngOnInit(): void {
    this.productsService.getProducts()
      .subscribe((data: Product[]) => {
        this.productsService.products = data;
        this.products = this.productsService.products;
      })
    this.productsService.productUpdated.subscribe( (data) => { 
      this.products = data;
      });
  }