Angular 2将父组件中的数据传递给子组件

koq*_*que 5 angular

我使用输入绑定将产品从父组件传递到子组件,它在第一次调用子组件时工作.我希望每次在父级中修改时,对filterProduct()中的产品的更改都会反映在子级中,但这种情况不会发生.我该如何实现这一目标.

父模板:

<div class="container-fluid">
<div class="col-sm-9">
    <app-product-card [products]=products></app-product-card>
</div>
Run Code Online (Sandbox Code Playgroud)

父组件:

@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;         
  }
}
Run Code Online (Sandbox Code Playgroud)

子组件:

@Component({
  selector: 'app-product-card',
  moduleId: module.id,
  templateUrl: 'product-card.component.html'
})

export class ProductCardComponent {
  @Input() products: Product[];
}
Run Code Online (Sandbox Code Playgroud)

小智 4

以下是可能对您有用的内容:

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();
  }
}
Run Code Online (Sandbox Code Playgroud)

子组件:

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
    });
  }
}
Run Code Online (Sandbox Code Playgroud)

服务:

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, type: 'Type 1' },
      { 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);
  }
}
Run Code Online (Sandbox Code Playgroud)

当我第一次开始编写角度应用程序时,我遇到了类似的问题。始终将数据从父组件传递到子组件并不是一种编写应用程序的易于管理的方式。特别是如果它是一个具有太多嵌套组件的大型应用程序。

在此示例中,我使用服务和事件发射器(都是角度框架的一部分)向子组件和父组件提供相关数据。

改进代码的一种方法是使用 rxjs。这就是角度事件发射器在幕后使用的。

更高级的解决方案是使用 ngrx/store(Angular 的 redux 库)。这特别适合大型应用程序。

无论您选择哪种解决方案,其想法都是有一个地方来维护应用程序的状态并避免过多嵌套数据。