我从 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标记)。
在我看来,基本上我正在迭代定义到父组件类(字符串数组)中的产品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)
从数组中删除具有此名称的对象的方法。
这是正确的还是在我的推理中我错过了什么?
另一个疑问是:处理事件和这种情况是否是一种整洁而正确的方式?