Angular 中 child 属性 的更改检测
Change detection for child property in Angular
我在 Angular 应用程序中有以下产品 object。该产品包含一系列订单和其他产品信息。
Product.ts
export interface Product {
ProductID: number;
ProductName: string;
Orders: Order[]
}
我需要在 child angular 组件中显示产品信息并生成订单摘要。
order-summary.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
}
}
order-summary.component.html
<b>{{_product.ProductName}}</b>
<b> ... show other product details </b>
<table> ... show generated order summary ... </table>
我相信每次产品 object 更改时,即使 Orders
数组未更改,它也会生成订单摘要 (generateOrderSummary
)。解决此问题的更好方法是什么?
我正在考虑为 Orders[] 添加另一个 属性,这样我就可以仅在更改订单时重新生成摘要。但是,产品已经包含订单,不确定它是否是一个好的设计。
order-summary.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 实现并使用 Angular OnChanges
hook with SimpleChanges
参数。它允许您检查它是否是组件的第一次调用,并比较 @Input
属性.
的先前值和当前值
尝试以下方法
顺序-summary.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
}
}
顺序-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>
我在 Angular 应用程序中有以下产品 object。该产品包含一系列订单和其他产品信息。
Product.ts
export interface Product {
ProductID: number;
ProductName: string;
Orders: Order[]
}
我需要在 child angular 组件中显示产品信息并生成订单摘要。
order-summary.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
}
}
order-summary.component.html
<b>{{_product.ProductName}}</b>
<b> ... show other product details </b>
<table> ... show generated order summary ... </table>
我相信每次产品 object 更改时,即使 Orders
数组未更改,它也会生成订单摘要 (generateOrderSummary
)。解决此问题的更好方法是什么?
我正在考虑为 Orders[] 添加另一个 属性,这样我就可以仅在更改订单时重新生成摘要。但是,产品已经包含订单,不确定它是否是一个好的设计。
order-summary.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 实现并使用 Angular OnChanges
hook with SimpleChanges
参数。它允许您检查它是否是组件的第一次调用,并比较 @Input
属性.
尝试以下方法
顺序-summary.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
}
}
顺序-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>