Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Child listens for parent event in Angular 2

In angular docs there is a topic about listening for child events from parents. That's fine. But my purpose is something reverse!. In my app there is an 'admin.component' that holds the layout view of admin page (sidebar menu,task bar, status etc..). In this parent component I configured router system for changing the main view between other pages of administrator. The problem is for saving things after change, the user clicks on save button in task bar (that is placed in admin.component) and the child component must listen to that click event for doing save staff.

like image 983
Hamed Hamedi Avatar asked Jun 07 '16 10:06

Hamed Hamedi


People also ask

How is an event passed from parent to child?

In a parent component you can use @ViewChild() to access child component's method/variable. Use the @Input() decorator in your child component to allow the parent to bind to this input. To bind a property from parent to a child you must add in you template the binding brackets and the name of your input between them.

What is @input and @output in Angular?

@Input() and @Output() allow Angular to share data between the parent context and child directives or components. An @Input() property is writable while an @Output() property is observable.

How does a child component communicate with a parent component in Angular?

The child component uses the @Output() property to raise an event to notify the parent of the change. To raise an event, an @Output() must have the type of EventEmitter , which is a class in @angular/core that you use to emit custom events.


2 Answers

For the sake of posterity, just thought I'd mention the more conventional solution to this: Simply obtain a reference to the ViewChild then call one of its methods directly.

@Component({   selector: 'app-child' }) export class ChildComponent {    notifyMe() {     console.log('Event Fired');   } }  @Component({   selector: 'app-parent',   template: `<app-child #child></app-child>` }) export class ParentComponent {    @ViewChild('child')   private child: ChildComponent;    ngOnInit() {     this.child.notifyMe();   } } 
like image 197
Stephen Paul Avatar answered Oct 13 '22 06:10

Stephen Paul


I think that this doc could be helpful to you:

  • https://angular.io/docs/ts/latest/cookbook/component-communication.html

In fact you could leverage an observable / subject that the parent provides to its children. Something like that:

@Component({   (...)   template: `     <child [parentSubject]="parentSubject"></child>   `,   directives: [ ChildComponent ] }) export class ParentComponent {   parentSubject:Subject<any> = new Subject();    notifyChildren() {     this.parentSubject.next('some value');   } } 

The child component can simply subscribe on this subject:

@Component({   (...) }) export class ChildComponent {   @Input()   parentSubject:Subject<any>;    ngOnInit() {     this.parentSubject.subscribe(event => {       // called when the notifyChildren method is       // called in the parent component     });   }    ngOnDestroy() {     // needed if child gets re-created (eg on some model changes)     // note that subsequent subscriptions on the same subject will fail     // so the parent has to re-create parentSubject on changes     this.parentSubject.unsubscribe();   }  } 

Otherwise, you could leverage a shared service containing such a subject in a similar way...

like image 20
Thierry Templier Avatar answered Oct 13 '22 04:10

Thierry Templier