这个Angular 5示例如何处理父组件和子组件之间的通信?

时间:2018-05-15 14:36:54

标签: javascript angular typescript angular-components angular-event-emitter

我从Angular开始,我对这个例子与父组件和子组件之间的通信有何关联有一些疑问。

所以我有这个PARENT COMPONENT。此组件用于显示项目列表(每个项目由子组件代表)。与此组件交互,我可以在此项列表中添加和删除项目。

这是父组件:

@Component({
  selector: 'app-products',
  templateUrl: './products.component.html'
})
export class ProductsComponent {

  productName = 'A Book';
  isDisabled = true;

  products = ['A Book', 'A Tree'];

  constructor() {

    setTimeout(
      () => {
        this.isDisabled = false;
      }, 3000)
  }


  onAddProduct() {
    this.products.push(this.productName);

  }

  onRemoveProduct(productName: string) {
    this.products = this.products.filter(p => p !== productName);
  }

}

这是它的模板:

<h1>My Products</h1>

<input *ngIf="!isDisabled" type="text" [(ngModel)]="productName">

<button *ngIf="!isDisabled" (click)="onAddProduct()">Add Product</button>

<app-product
    (productClicked)="onRemoveProduct(product)"
    *ngFor="let product of products"
    [productName]="product">
</app-product>

然后我将子组件表示由te父组件处理的列表中的单个项目。这是子组件:

@Component({
  selector: 'app-product',
  templateUrl: './product.component.html',
  styleUrls: ['./product.component.css']
})
export class ProductComponent {

  @Input() productName: string;

  @Output() productClicked = new EventEmitter();

  onClicked() {
    this.productClicked.emit();
  }

}

这是te儿童模板:

<article class="product" (click)="onClicked()">
  <div>{{ productName }}</div>
  <p>An awesome product!</p>
</article>

好的,现在我对这两个组件如何相互作用产生了疑问:

在父组件模板中:

<app-product
    (productClicked)="onRemoveProduct(product)"
    *ngFor="let product of products"
    [productName]="product">
</app-product>

指的是子组件(由 app-product 标记)。

在我看来,基本上我正在迭代定义到父组件类(字符串数组)中的产品列表,并且每个字符串都传递给 productName < / strong>变量定义到子组件类中,为此我在子组件类中使用此属性上的 @Input()装饰器:

@Input() productName: string;

基本上,这个 @Input()装饰器将父组件置于每次迭代时将值“注入”子组件属性。

是吗?还是我错过了什么?

然后我有从项目列表中处理项目删除的行为:当单击列表的元素时(由子组件实现)。此元素将从列表中删除(从页面中删除)。

它是如何工作的(我的想法):

每个元素在子组件视图中由此代码表示:

<article class="product" (click)="onClicked()">
  <div>{{ productName }}</div>
  <p>An awesome product!</p>
</article>

单击对象时,会在子组件类中执行 onClicked()事件。我无法直接从子组件类中删除所选对象,因为项目数组已定义到父组件类中。所以这个方法会发出一个事件:

onClicked(){     this.productClicked.emit();   }

拥有“type”productClicked(它是一种事件类型还是什么?)。在父组件视图中收到此事件:

(productClicked)="onRemoveProduct(product)"

调用 onRemoveProduct(product)方法,从数组中删除具有此名称的对象。

这是正确的还是在我的推理中我错过了什么?

另一个疑问是:它是处理事件和这种情况的一种干净而正确的方法吗?

TNX

1 个答案:

答案 0 :(得分:0)

在这两种情况下你都是对的!

根据angular guide,这是处理父/子组件之间通信的正确方法。