Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

388
Visualizações
Angular 2: How do I emit an event up through multiple nested components?

I have one "smart" component called ItemsComponent and two nested "dumb" components, ItemsListComponent and ItemComponent.

ItemsComponent's html template contains ItemsListComponent.

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

and it has a function called deleteItem:

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

ItemsListComponent contains ItemComponent:

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

So the html structure is like this:

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

ItemComponent has a button

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

and an event emitter for deleteItem:

@Output() doDelete = new EventEmitter();

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

When the delete button is clicked in ItemComponent, the event only bubbles up to it's immediate parent, ItemsListComponent, but doesn't make it to ItemsComponent unless I add identical event emitter functionality to the ItemsListComponent.

Smelly ItemsListComponent:

@Output() doDelete = new EventEmitter();

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

It works this way, but ItemsListComponent now shares code smell with ItemsComponent since they both have the same event emitter stuff and the event has to be passed from one component to another on it's way up.

Is there a better way to do this?

about 4 years ago · Santiago Trujillo
2 Respostas
Responde à pergunta

0

As you've realised, custom angular events don't bubble, so if you have a deeply nested component and you want to pass an event to a higher component, every component in between has to delegate the event upwards.

Another option is to move your deleteItem functionality to a service that is injected into one of your lower level components. That way, the function can be called at the point where it happens, rather than having to bubble the event up your view hierarchy.

about 4 years ago · Santiago Trujillo Relatório

0

Actually, you can make it happen using a CustomEvent rather than an EventEmitter. This is just a workaround, especially because Angular communication patterns are well described in the Angular documentation and many other places.

Basically, you need to trigger a CustomEvent from the inner child and simply listen for it on the outermost component (the grandparent).

OutermostComponent

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

ChildComponent

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

InnerChildComponent

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

Here's a working blitz: https://stackblitz.com/edit/angular-5wv8p5

about 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda