我从 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>
这是指子组件(按应用产品标记)。
在我看来,基本上我正在迭代父组件类(字符串数组)中定义的产品列表,并且这些字符串中的每一个都传递给定义到子组件类中的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)="onRemoveProduct(product)"
调用从数组中删除具有此名称的对象onRemoveProduct(product)
方法。
它是否正确或在我的推理中我错过了什么?
另一个问题是:处理事件和这种情况是否是一种简洁而正确的方法?
在这两种情况下你都是对的!
根据角度指南,这是处理父/子组件之间通信的正确方法。