Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular 2 : How to pass function into child component

Tags:

angular

In an Angular 2 app, say i have a 'SaveComponent' where clicking its save button calls a function isDirty() that returns true or false (true if the content of the parent component has been modified). Note the reason for the 'SaveComponent' is that it has styles and other 'widgets' associated with it that are shared among many components.

currently there is a isDirty function defined in each of the parent components, and the function is passed to SaveComponent as follows inside the parent template:

<save-component [isDirty]="isDirty"> </save-component>

if you care to see, a simplified version of SaveComponent is defined something like this...

import {Component, Input} from 'angular2/core';

@Component({
  selector: 'save-component',
  templateUrl: 'who-cares-to-know.component.html'
})

export class SaveComponent {
  @Input() isDirty;
}

It works only initially. It seems that the isDirty function only returns false (or only called once?) even when the content is modified. Note that the function does work correctly when it's called from the parent component.

What's wrong? Is it possible to pass function from parent to child component via @Input or some other means? Thanks!

like image 807
totoro Avatar asked May 03 '16 19:05

totoro


People also ask

Can we pass function from parent to child in Angular?

@Input Decorator: This is used to define an input property and it is used to send data from parent component to child component. @Output Decorator: This is used to bind a property of the type of Angular EventEmitter class and it is used to pass data from child component to parent component.

Why do we use @input in Angular?

Use the @Input() decorator in a child component or directive to let Angular know that a property in that component can receive its value from its parent component. It helps to remember that the data flow is from the perspective of the child component.


2 Answers

The problem is that you lose the context of your method when referencing it, i.e. the "this" keyword.

I would use something like that:

getIsDirty() {
  return () => {
    return this.isDirty();
  }
}

With the arrow function, you will be able to use the lexical this. The latter corresponds to the component instance itself.

And provide it to the sub component this way:

<save-component [isDirty]="getIsDirty()"> </save-component>
like image 157
Thierry Templier Avatar answered Nov 11 '22 12:11

Thierry Templier


I realize this is old, but I just ran into the issue so hopefully this can help someone moving forward. I also tried to edit the first answer but that was rejected, and I don't have enough reputation to comment on the first answer.

The first answer is correct, but it's not complete. In order to call the parent function in the child component you need to treat @Input() isDirty as a function as opposed to a property.

Call this.isDirty() as opposed to this.isDirty in order to run the function.

like image 21
Jake Avatar answered Nov 11 '22 13:11

Jake