簡體   English   中英

Angular:如何通過多個嵌套組件發出事件?

[英]Angular: How do I emit an event up through multiple nested components?

我有一個名為ItemsComponent的“智能”組件和兩個嵌套的“啞”組件ItemsListComponentItemComponent

ItemsComponent的 html 模板包含ItemsListComponent

// ItemsComponent
<div>
  // ItemsListComponent
  <app-items-list
    [items]="items"
    (doDelete)="deleteItem($event)"
  >
  </app-items-list>
<div>

它有一個名為 deleteItem 的function

deletItem(item) {
  // code to handle item deletion...
}

ItemsListComponent包含ItemComponent

// ItemsListComponent    
<ul *ngFor="let item of items">
  // ItemComponent
  <app-item
   [item]="item"
   (doDelete)="deleteItem($event)"
  >
  </app-item>
</ul>

所以html的結構是這樣的:

ItemsComponent (app-items)
    - ItemsListComponent (app-items-list)
        - ItemComponent (app-item)

ItemComponent有一個按鈕

<button (click)="deleteItem(item)">

deleteItem的事件發射器:

@Output() doDelete = new EventEmitter();

deleteItem(item) {
  this.doDelete.emit(item);
}

當在ItemComponent中單擊刪除按鈕時,事件只會冒泡到它的直接父級ItemsListComponent ,但不會進入ItemsComponent除非我向ItemsListComponent添加相同的事件發射器功能。

臭味ItemsListComponent

@Output() doDelete = new EventEmitter();

deleteItem(item) {
  this.doDelete.emit(item);
}

它以這種方式工作,但ItemsListComponent現在與ItemsComponent共享代碼味道,因為它們都具有相同的事件發射器內容,並且事件必須從一個組件傳遞到另一個組件。

有一個更好的方法嗎?

正如您所知,自定義角度事件不會冒泡,因此如果您有一個深層嵌套的組件,並且您希望將事件傳遞給更高的組件,則兩者之間的每個組件都必須向上委派事件。

另一種選擇是將deleteItem功能移動到注入其中一個較低級別組件的服務。 這樣,可以在它發生的位置調用該函數,而不必將事件冒泡到視圖層次結構中。

實際上,您可以使用CustomEvent而不是EventEmitter來實現它。 這只是一種解決方法,特別是因為 Angular 通信模式在Angular 文檔和許多其他地方都有很好的描述。

基本上,您需要從內部子組件觸發CustomEvent並在最外層組件(祖父母組件)上簡單地監聽它。

最外層組件

@Component({
 selector: 'outermost',
 template: `<child></child>`
})
export class OutermostComponent {
      @HostListener('FormSubmitCustomEvent', ['$event'])
      onCustomEventCaptured(event: any) {
        console.log('Event Received', event.detail);
      }
}

子組件

@Component({
  selector: 'child',
  template: `<inner-child></inner-child>`
})
export class ChildComponent {
   
}

內部子組件

@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);
  }
}

這是一個有效的閃電戰: https://stackblitz.com/edit/angular-5wv8p5

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM