簡體   English   中英

Angular 中子屬性的更改檢測

[英]Change detection for child property in Angular

我在 Angular 應用程序中有以下 Product 對象。 該產品包含一系列訂單和其他產品信息。

產品.ts

export interface Product { 
    ProductID: number;
    ProductName: string;
    Orders: Order[]
}

我需要在子角度組件中顯示產品信息並生成訂單摘要。

訂單摘要.component.ts

export class OrderSummary {

  _product: Product;
  @Input() set product(value: Product) {
    this._product = value;
    this.generateOrderSummary(value.Orders);
  }

  private generateOrderSummary(orders: Order[]) {
   // Logic to generate order summary
  }

}

訂單摘要.component.html

<b>{{_product.ProductName}}</b>
<b> ... show other product details </b>
<table> ... show generated order summary ... </table>

我相信每次產品對象更改時,即使Orders數組沒有更改,它也會生成訂單摘要( generateOrderSummary )。 解決此問題的更好方法是什么?

我正在考慮為 Orders[] 添加另一個屬性,因此只有在訂單更改時我才能重新生成摘要。 但是,產品已經包含訂單,不確定它是否是一個好的設計。

訂單摘要.component.ts

export class OrderSummary {
  _product: Product;
  @Input() set product(value: Product) {
    this._product = value;
  }

  @Input() set orders(value: Orders[]) {
    this.generateOrderSummary(value.Orders);
  }

  private generateOrderSummary(orders: Order[]) {
   // Logic to generate order summary
  }
}

有沒有更好的解決方案?

在這種情況下,您可以跳過@Input的 setter 實現並使用帶有SimpleChanges參數的 Angular OnChanges鈎子。 它允許您檢查它是否是組件的第一次調用,並比較@Input屬性的先前值和當前值。

嘗試以下

訂單摘要.component.ts

import { Component, Input, OnChanges, SimpleChanges } from '@angular/core';

export class OrderSummary implements OnChanges {
  @Input() product: Product;

  ngOnChanges(changes: SimpleChanges) {
    if (!!changes.product) {
      if (changes.product.firstChange) {                 // <-- first time the component is rendered
        this.generateOrderSummary(this.product.orders);  // <-- could also be `changes.product.currentValue.orders`
      } else if (                                        // <-- true only if different `orders` value
        !!changes.product.previousValue &&
        !!changes.product.previousValue.orders &&
        changes.product.previousValue.orders !== changes.product.currentValue.orders
      ) {
        this.generateOrderSummary(product.orders);
      }
    }
  }

  private generateOrderSummary(orders: Order[]) {
    // Logic to generate order summary
  }
}

訂單摘要.component.html

<b>{{ product?.ProductName }}</b>
<b> ... show other product details </b>
<table> ... show generated order summary ... </table>

我認為你可以像這樣使用 observables 和 rxjs 邏輯。

export class OrderSummary implements OnInit {
  product$: Observable<Product>;
  private productSubject$ = new Subject();

  @Input() set product(value: Product) {
    this.productSubject$.next(value);
  }
  
  ngOnInit(): void {
    this.product$ = this.productSubject$.pipe(
          distinctUntilChanged((prev: Product, curr: Product) => prev.ProductId === curr.ProductId), 
          map(prod => {
             this.generateOrderSummary(prod.orders);
             return prod;
          })
  }


  private generateOrderSummary(orders: Order[]) {
   // Logic to generate order summary
  }

}

並在您的 html 中訂閱產品

<div *ngIf="product$ | async as product">
   <b>{{product.ProductName}}</b>
   <b> ... show other product details </b>
   <table> ... show generated order summary ... </table>
</div>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM