簡體   English   中英

當組件之間的共享對象更改時,Angular 2+ Catch 事件

[英]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 中更新產品的結果:

在 ProductsSalesComponent 中更新產品的結果

編輯我在 StackBlitz 中創建了一個項目,以顯示當對象“產品”更改時組件“ProductSaleTotal”的 ngOnChange 事件如何不觸發的問題https://stackblitz.com/edit/angular-fcevey?file= src%2Fapp%2Fproducts-sale-total%2Fproducts-sale-total.component.ts

app-products-sale-totalapp-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.

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