我有一个名为ItemsComponent的 "智能"组件和两个嵌套的"哑"组件,ItemsListComponent和ItemComponent.
ItemsComponent的html模板包含ItemsListComponent.
// ItemsComponent
<div>
// ItemsListComponent
<app-items-list
[items]="items"
(doDelete)="deleteItem($event)"
>
</app-items-list>
<div>
Run Code Online (Sandbox Code Playgroud)
它有一个名为deleteItem的函数:
deletItem(item) {
// code to handle item deletion...
}
Run Code Online (Sandbox Code Playgroud)
ItemsListComponent包含ItemComponent:
// ItemsListComponent
<ul *ngFor="let item of items">
// ItemComponent
<app-item
[item]="item"
(doDelete)="deleteItem($event)"
>
</app-item>
</ul>
Run Code Online (Sandbox Code Playgroud)
所以html结构是这样的:
ItemsComponent (app-items)
- ItemsListComponent (app-items-list)
- ItemComponent (app-item)
Run Code Online (Sandbox Code Playgroud)
ItemComponent有一个按钮
<button (click)="deleteItem(item)">
Run Code Online (Sandbox Code Playgroud)
和deleteItem的事件发射器:
@Output() doDelete = new EventEmitter();
deleteItem(item) {
this.doDelete.emit(item);
}
Run Code Online (Sandbox Code Playgroud)
当在ItemComponent中单击删除按钮时,该事件仅冒泡到它的直接父项ItemsListComponent,但不会使它成为ItemsComponent,除非我向ItemsListComponent添加相同的事件发射器功能.
Smelly ItemsListComponent:
@Output() doDelete = new EventEmitter();
deleteItem(item) {
this.doDelete.emit(item);
}
Run Code Online (Sandbox Code Playgroud)
它以这种方式工作,但ItemsListComponent现在与ItemsComponent共享代码气味,因为它们都具有相同的事件发射器内容,并且事件必须在一个组件上传递到另一个组件.
有一个更好的方法吗?
sno*_*ete 21
正如您所知,自定义角度事件不会冒泡,因此如果您有一个深层嵌套的组件,并且您希望将事件传递给更高的组件,则两者之间的每个组件都必须向上委派事件.
另一种选择是将您的deleteItem功能转移到注入其中一个较低级别组件的服务.这样,可以在它发生的位置调用该函数,而不必将事件冒泡到视图层次结构中.
Jos*_*man 13
CustomEvent实际上,您可以使用 a而不是 来实现它EventEmitter。这只是一种解决方法,特别是因为Angular 文档和许多其他地方都很好地描述了 Angular 通信模式。
基本上,您需要从内部子组件触发 aCustomEvent并简单地在最外层组件(祖父母)上监听它。
最外层组件
@Component({
selector: 'outermost',
template: `<child></child>`
})
export class OutermostComponent {
@HostListener('FormSubmitCustomEvent', ['$event'])
onCustomEventCaptured(event: any) {
console.log('Event Received', event.detail);
}
}
Run Code Online (Sandbox Code Playgroud)
子组件
@Component({
selector: 'child',
template: `<inner-child></inner-child>`
})
export class ChildComponent {
}
Run Code Online (Sandbox Code Playgroud)
内部子组件
@Component({
selector: 'inner-child',
template: `<button (click)="onSubmit()"></button>`
})
export class InnerChildComponent {
constructor(private elementRef: ElementRef) {}
onSubmit(): void {
const event: CustomEvent = new CustomEvent('FormSubmitCustomEvent', {
bubbles: true,
detail: { data: 'Hello from Inner Child' }
});
this.elementRef.nativeElement.dispatchEvent(event);
}
}
Run Code Online (Sandbox Code Playgroud)
这是一个有效的闪电战:https ://stackblitz.com/edit/angular-5wv8p5
| 归档时间: |
|
| 查看次数: |
8409 次 |
| 最近记录: |