Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular2 passing a function to a directive via attribute

I'm trying to bind a function in a parent component into a property on a child component.

This is what I have

@Component({
  selector: 'awesome',
  templateUrl: 'awesome.html'
})
export class AwesomeComponent {

@Input() callback: Function;

ngOnInit() {

    this.callback();//Error, this.callback is not a function,  but contains a string value on the fuction call
    }
}

This is how i'm using it

<awesome callback="nameOfFuncFromAnotherComponent"></awesome>

but it doesn't seem to work

like image 547
Steven Yates Avatar asked Feb 12 '16 15:02

Steven Yates


People also ask

What is directive attribute?

Attribute directives are used to change the appearance or behavior of an element. Examples of attributes directives are ngStyle , ngClass , ngModel. ngStyle — used to apply styles that will change the appearance. ngClass — used to apply CSS classes to change the appearance.

How do you create an attribute directive?

Steps to create a custom attribute directiveAssign the attribute directive name to the selector metadata of @Directive decorator. Use ElementRef class to access DOM to change host element appearance and behavior. Use @Input() decorator to accept user input in our custom directive.

What is the use of attribute directive in Angular?

Attribute directives listen to and modify the behavior of other HTML elements, attributes, properties, and components. Adds and removes a set of CSS classes. Adds and removes a set of HTML styles. Adds two-way data binding to an HTML form element.

Can a directive have input?

Input data into a DirectiveWe can also extend or modify the behavior or functionality of a directive by inputtting data into the directive.


3 Answers

Your code only binds the string nameOfFuncFromAnotherComponent to the callback attribute (and property if it exists). Angular doesn't interpret the value at all.

To make Angular manage the binding use

<awesome [callback]="nameOfFuncFromAnotherComponent"></awesome>

With this syntax Angular also evaluates the value

<awesome callback="{{nameOfFuncFromAnotherComponent}}"></awesome>

but converts the result to a string (calls .toString()) before the assignment.

Thanks to @MarkRajcok for clarification :)

like image 162
Günter Zöchbauer Avatar answered Nov 11 '22 13:11

Günter Zöchbauer


i think using eventEmitter in the case of function is much more better becouse of the passing the function by reference will make some problems with the this

so my suggestion is to do the following

cm1.component.html

<cm2-component (childFunc)="myFunc()"></cm2-component>

cm2.component.ts

import { Output, EventEmitter } from '@angular/core';
export class Cm2 {
  @Output('childFunc') childFunc: EventEmitter<any> = new EventEmitter();
  constructor() { }
  invokeMyFunc(){
    this.childFunc.emit()
  }
}
like image 43
Mostafa Ahmed Avatar answered Nov 11 '22 12:11

Mostafa Ahmed


There is really no need for pushing callback into @Input property. You can use #local_variable wich provides a reference to the child component. That way you will have access to all its properties and methods from the parent template. See ng2 documentation on component interaction.

like image 1
Dzenad Dedic Avatar answered Nov 11 '22 12:11

Dzenad Dedic