【发布时间】:2018-10-25 10:50:06
【问题描述】:
我从 Angular 开始,我对这个与父组件和子组件之间的通信相关的示例的工作原理有一些疑问。
所以我有这个父组件。该组件用于显示项目列表(每个项目由子组件表示)。通过与这个组件交互,我可以在这个项目列表中添加和删除项目。
这是父组件:
@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>
然后我让子组件表示由父组件处理的列表中的单个项目。这是子组件:
@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();
}
}
这是子模板:
<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 标记)。
在我看来,基本上我正在迭代定义到父组件类(字符串数组)中的 products 列表,并且这些字符串中的每一个都传递给定义的 productName 变量进入子组件类,为此我在子组件类的此属性上使用@Input() 装饰器:
@Input() productName: string;
基本上,这个 @Input() 装饰器使父组件神圣化,以便在每次迭代时将值“注入”到子组件属性中。
是吗?还是我错过了什么?
然后我有处理从项目列表中删除项目的行为:单击列表的元素时(由子组件实现)。此元素从列表中删除(因此从页面中删除)。
它是如何工作的(我的想法):
每个元素在子组件视图中都由这段代码表示:
<article class="product" (click)="onClicked()">
<div>{{ productName }}</div>
<p>An awesome product!</p>
</article>
当点击一个对象时,它会在子组件类中执行onClicked() 事件。我无法直接从子组件类中删除所选对象,因为项目数组已定义到父组件类中。所以这个方法会发出一个事件:
onClicked() {
this.productClicked.emit();
}
具有“类型”productClicked(是事件类型还是什么?)。在父组件视图中接收到这个事件:
(productClicked)="onRemoveProduct(product)"
调用onRemoveProduct(product) 方法从数组中删除具有此名称的对象。
这是正确的还是在我的推理中我错过了什么?
另一个疑问是:这是处理事件和这种情况的一种简洁正确的方法吗?
【问题讨论】:
-
你所解释的一切都是正确的,这正是你应该如何处理这种沟通。赞一个!
-
看起来正确。在使用 Angular 1.5 年之后,我发现没有什么是我不会以不同的方式做的。
标签: javascript angular typescript angular-components angular-event-emitter