OnChanges 不会检测到更改

OnChanges won't detect the changes

我正在创建一个简单的应用程序。然后我将一个数组传递给子组件。当我从数组中删除一个项目时,ngOnChanges 不会检测到更改,除非我刷新页面。

我只能在第一个页面加载时记录更改一次,但在数组更改时不能。

提前感谢您的宝贵时间。

父组件:

<div class="wrapper">
  <div class="cart-container">
    <h1>In Cart</h1>
    <mat-card class="list-item" *ngFor="let x of shoppingCart">
      <div class="list-title">{{ x.title }}</div>
      <button color="warn" mat-icon-button (click)="deleteFromCart(x)">
        <mat-icon class="material-icons">clear</mat-icon>
      </button>
    </mat-card>
    <app-calculator [shoppingCart]="shoppingCart"></app-calculator>
  </div>
  <hr />
  <app-favourites></app-favourites>
</div>
import { Component, Input, OnInit } from '@angular/core';
import { ProductModel } from 'src/app/models/product/product-model';
import { CartService } from 'src/app/services/cart.service';

@Component({
  selector: 'app-shopping-cart',
  templateUrl: './shopping-cart.component.html',
  styleUrls: ['./shopping-cart.component.scss']
})
export class ShoppingCartComponent implements OnInit {
  public shoppingCart: ProductModel[] = [];

  constructor(
    private cartService: CartService
  ) {}

  ngOnInit(): void {
    this.getItems();
  }

  getItems(): void {
    this.shoppingCart = this.cartService.getItems();
  }

  deleteFromCart(item: ProductModel): void {
    this.shoppingCart = this.cartService.deleteItemFromCart(item);
  }
}

子组件:

import { Component, Input, OnChanges, SimpleChanges } from '@angular/core';
import { ProductModel } from 'src/app/models/product/product-model';

@Component({
  selector: 'app-calculator',
  templateUrl: './calculator.component.html',
  styleUrls: ['./calculator.component.scss']
})
export class CalculatorComponent implements OnChanges {
  @Input() shoppingCart: ProductModel[] = [];
  public total: number = 0;

  constructor() {}

  ngOnChanges(changes: SimpleChanges): void {
    console.log(changes)
  }
}

我想问题出在您的更改检测上。我不确定您的服务到底是什么样子,以及它是 returns 可观察的还是数组,所以检查问题出在哪里的最简单方法是:

  1. 在您的 deleteFromCart() 中记录 this.shoppingCart。如果它注销了正确的结果(因此该项目被删除) - 这意味着问题出在变化检测上。也许您没有再次分配数组,您只是在修改它,所以 angular 不会检查更改。这意味着您有两种选择来解决问题。更好的方法:

    deleteFromCart(item: ProductModel): void {
      this.shoppingCart = [...this.cartService.deleteItemFromCart(item)];
    }
    

    这会将一个全新的数组分配给 this.shoppingCart 并会触发 angular 检查更改。 “更糟糕”的方法是在构造函数中添加 private changeDetectorRef: ChangeDetectorRef,然后:

    deleteFromCart(item: ProductModel): void {
      this.shoppingCart = this.cartService.deleteItemFromCart(item);
      this.changeDetectorRef.markForChanges()
    }
    

    这将告诉 angular 他必须检查是否有任何更改 - 但这不是一个好方法(最好避免 changeDetectorRef

  2. 如果您的日志显示结果仍然相同 - 那么这意味着您的服务做错了什么,然后您应该检查那里发生了什么 - 您可以粘贴代码在这里,我们可以提供帮助。

试试这个:

  deleteFromCart(item: ProductModel): void {
    this.shoppingCart = [...this.cartService.deleteItemFromCart(item)];
  }

但更正确的做法是 cartService.deleteItemFromCart returns 未删除项目的项目数组的副本,而不是返回删除项目的同一数组。

你是对的,添加或删除项目不会引发 onChanges 事件,因为数组对象的引用没有改变。如果你想强制 onChanges 那么你每次修改数组时都必须创建一个新的数组对象。像这样

      deleteFromCart(item: ProductModel): void {
    this.shoppingCart = [...this.cartService.deleteItemFromCart(item)];
  }

否则,如果您只想检查是否引发了数组更改事件,您还有很多其他方法,例如,您可以将数组放在一个服务中,它可以从父组件和子组件访问,或者您可以创建一个主题并在子组件中订阅它。