我使用输入绑定将产品从父组件传递到子组件,它在第一次调用子组件时工作.我希望每次在父级中修改时,对filterProduct()中的产品的更改都会反映在子级中,但这种情况不会发生.我该如何实现这一目标.
父模板:
<div class="container-fluid"> <div class="col-sm-9"> <app-product-card [products]=products></app-product-card> </div>
父组件:
@Component({ selector: 'app-appliances-product-card',moduleId: module.id,templateUrl: 'appliances-product-card.component.html' }) export class AppliancesProductCardComponent implements OnInit{ products: Product[]; filterProduct(filter) { this.products = this.filteredProducts; } }
子组件:
@Component({ selector: 'app-product-card',templateUrl: 'product-card.component.html' }) export class ProductCardComponent { @Input() products: Product[]; }
解决方法
以下是可能对您有用的东西:
https://plnkr.co/edit/S47fBh2xdT1gp2zrznk4?p=preview
父代组件和子组件都将使用服务来获取数据,而不是将数据从父组件传递到子组件.
父组件:
import { Component,OnInit } from '@angular/core'; import { Product } from './product' import { ProductsService } from './products.service'; @Component({ selector: 'app-appliances-product-card',template: ` <div class="container-fluid"> <button (click)="filterProduct('Type 1')">Filter Type 1</button> <button (click)="filterProduct('')">Clear Filter</button> <div class="col-sm-9"> <app-products-card></app-products-card> </div> </div> ` }) export class AppliancesProductCardComponent implements OnInit { products: Product[]; constructor(private _productsService: ProductsService){ } filterProduct(type: string) { this.products = this._productsService.filterProduct(type); } ngOnInit() { this.products = this._productsService.getAllProducts(); } }
子组件:
import { Component,OnInit,Input } from '@angular/core'; import { Product } from './product'; import { ProductsService } from './products.service'; @Component({ selector: 'app-products-card',template: ` <h1>Product Card</h1> <div *ngFor="let product of products">{{product.name}} - {{product.type}}</div> ` }) export class ProductsCardComponent implements OnInit { constructor(private _productsService: ProductsService){ } ngOnInit() { this.products = this._productsService.getAllProducts(); this._productsService.filteredProducts.subscribe(products => { console.log(products); this.products = products }); } }
服务:
import { EventEmitter,Injectable } from '@angular/core'; import { Product } from './product'; export class ProductsService { filteredProducts = new EventEmitter<Product[]>; private products: Product[] = [ { id: 1,name: 'Product 1',price: 10.50,type: 'Type 1' },{ id: 2,name: 'Product 2',price: 15.50,{ id: 3,name: 'Product 3',price: 1.50,type: 'Type 2' },{ id: 4,name: 'Product 4',price: 100.50,type: 'Type 3' } ]; getAllProducts(): Product[] { return this.products.slice(); } filterProduct(type: string): Product[]{ let filteredProducts = this.products.filter(p => !type || p.type == type).slice(); this.filteredProducts.emit(filteredProducts); } }
我第一次开始编写角度应用程序时遇到了类似的问题.始终将数据从父组件传递到子组件不是编写应用程序的可管理方式.特别是如果它是一个包含太多嵌套组件的大应用程序.
在这个例子中,我使用服务和事件发射器(角度框架的一部分)来向子组件和父组件提供相关数据.
改进代码的一种方法是使用rxjs.这是角度事件发射器在场景后面使用的.
更高级的解决方案是使用ngrx / store(针对Angular的redux库).这特别适用于大型应用.
无论您选择哪种解决方案,我们的想法都是有一个地方来维护应用程序的状态并避免过多地嵌套数据.