[英]Angular 2+ Catch event when shared object between components changes
我有 3 個組件(Sales、ProductSales、ProductTotals),它們共享一系列產品,但 ProductsTotal 組件沒有讀取數組的變化。 父組件 (Sales) 初始化產品數組並設置為子組件的輸入,ProductSales 組件更改產品數組的值(添加、刪除、更改單價等屬性等),ProductTotals 組件讀取array 並不斷地進行操作以獲得產品的單價總和並顯示它們。
銷售組件.html
<app-products-sale-total class="full-wid" [products]="products"></app-products-sale-total>
<app-products-sale class="full-wid" [products]="products"></app-products-sale>
為了顯示總數,我做了這個ProductTotals.html
{{products.length}}
<strong>Taxes:</strong> {{taxes|currency}}
<strong>Subtotal:</strong> {{subtotal|currency}}
<strong>Total:</strong> {{total|currency}}
ProductsTotal.ts
import { Component, OnInit, Input, OnChanges, OnDestroy, SimpleChange } from '@angular/core';
import { ProductSale } from '../product-sale-detail/product-sale-detail.component';
@Component({
selector: 'app-products-sale-total',
templateUrl: './products-sale-total.component.html',
styleUrls: ['./products-sale-total.component.scss']
})
export class ProductsSaleTotalComponent implements OnChanges {
@Input() products: Array<ProductSale> = [];
total: number = 0;
subtotal: number = 0;
taxes: number = 0;
constructor() {
}
ngOnChanges(changes: import("@angular/core").SimpleChanges): void {
calculateTotalFields();
console.log(changes);
}
calculateTotalFields(): void {
let total = 0;
let subtotal = 0;
let taxes = 0;
this.products.forEach(x => {
const totalProduct = x.UnitPrice * x.Quantity;
const taxesProduct = totalProduct * 0.16;
total += totalProduct;
subtotal += totalProduct - taxesProduct;
taxes += taxesProduct;
});
this.total = total;
this.taxes = taxes;
this.subtotal = subtotal;
}
}
問題是即使產品的對象正在改變,也只進入 ngOnChanges 方法一次。
在 ProductsSalesComponent 中更新產品的結果:
編輯我在 StackBlitz 中創建了一個項目,以顯示當對象“產品”更改時組件“ProductSaleTotal”的 ngOnChange 事件如何不觸發的問題https://stackblitz.com/edit/angular-fcevey?file= src%2Fapp%2Fproducts-sale-total%2Fproducts-sale-total.component.ts
app-products-sale-total
和app-products-sale
都是不同的組件,因此要與它們通信,您需要使用app-products-sale
@Output()
並將對象數組傳遞給app-products-sale-total
...您可以在此StackBlitz 鏈接中找到完整的工作示例
您的ProductSaleDetailComponent.ts
是...
export class ProductSaleDetailComponent implements OnInit {
@Input() product: ProductSale;
@Input () index: number;
@Output() productData = new EventEmitter();
constructor() { }
ngOnInit() {
this.product.Quantity = 1;
}
changeInput(p){
this.productData.emit({event: 'add',value:p, index : this.index});
}
}
您的ProductsSaleComponent模板是...
<button type="button" (click)="addProduct()">Add Product!</button>
<div *ngFor="let product of products; let i=index">
<div>
<app-product-sale-detail [product]="product" [index]="i" (productData)= "productOutput($event)" ></app-product-sale-detail>
</div>
<div>
<button aria-label="Delete" color="warn" (click)="removeProduct(i)">
Remove Product
</button>
</div>
</div>
您的ProductSaleComponent.ts是...
export class ProductsSaleComponent implements OnInit {
@Input() products: Array<ProductSale> = [];
@Output() ProductOutputData = new EventEmitter();
constructor() { }
ngOnInit() {
console.log('product Sale',new ProductSale());
}
addProduct() {
this.products.push(new ProductSale());
}
removeProduct(index: number) {
this.ProductOutputData.emit({event:'remove', index: index, value : this.products[index]} );
this.products.splice(index, 1);
}
productOutput(event){
this.ProductOutputData.emit(event);
}
}
所以,基本上你需要@Input() and
@Output()` 鏈來分別在子父之間進行通信..
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.