1
votes

How to listen events from child template inside a child component when they are called from parent template?

I have 2 components: app.ts and child.ts;

app.ts:

@Component({
    selector: 'app',
    template: '<button>Main button</buton><router-outlet></router-outlet>',
    encapsulation: ViewEncapsulation.None,
    directives: [ROUTER_DIRECTIVES],
})
@RouteConfig([
    {path: '/child/', component: ChildCmp, as: 'Child'}
])
export class AppCmp {
}

child.ts:

@Component({
    selector: 'child',
    template: 'This is child page!'
})
export class AppCmp {

    // This method should be called, when mail button is pressed
    onChange() {
    }
}

I don't want to add click event to button, instead I would like to add some kind of listener for onChange function in child component so it listens when button in parent view is clicked. I've tried with HostListener, but it only triggers, when HostListener is added to parent component.

1
I am not sure I understand your question. Do you really want the ChildCmp to listen on the button in the AppCmp? This would violate the Component structure paradigm of angular2. A component should have no knowledge of a potential parent component. Why not listen to the button click event in AppCmp (the parent) and then call the function onChange() on the client? - Guenter Guckelsberger
Correct, the reason I'm doing it that I'm having a language selector on top of the page (which is parent component) and I want to reload the content in child component when user changes the language. - Hurley

1 Answers

1
votes

This is how I would do it, note however that I am getting rid of the routing, you will have to figure out how to do the same thing if you really need routing in the way you have it, personally if I was to use routing I would put both parent and child components in the same route, and then I could do something similar to below:

@Component({
    selector: 'app',
    template: '<button (click)="switchLanguage('German')">Main button</buton>
               <child [language]="selectedLanguage"></child>',
    encapsulation: ViewEncapsulation.None,
    directives: [ROUTER_DIRECTIVES, ChildCmp],
})
export class AppCmp {
    public selectedLanguage:string="English";

    public switchLanguage(newLanguage:string):void{
        this.selectedLanguage=newLanguage;
    }
}

child.ts

@Component({
    selector: 'child',
    template: 'This is child page! with language {{language}}'
})
export class ChildCmp {
    private _language:string;
    @Input()
    public get language():string{
        return this._language;
    };
    public set language(newValue:string):void {
        this._language=newValue;
        this.onChange();
    }
    // This method should be called, when mail button is pressed
    onChange() {
    }
}

Briefly, this works by updating the language binding on the child from the parent, and every time the language binding is changed on the parent the setter method for language on the child will be called, thus you can do whatever you need there like running the onChanged method.