Angular2 передает функцию директиве через атрибут

Я пытаюсь связать функцию родительского компонента со свойством дочернего компонента.

Это то, что у меня есть

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

Вот как я его использую

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

но это не работает


person Steven Yates    schedule 12.02.2016    source источник


Ответы (4)


Ваш код только привязывает строку nameOfFuncFromAnotherComponent к атрибуту callback (и свойству, если оно существует). Angular вообще не интерпретирует значение.

Чтобы заставить Angular управлять привязкой, используйте

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

С этим синтаксисом Angular также оценивает значение

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

но преобразует результат в строку (вызывает .toString()) перед назначением.

Спасибо @MarkRajcok за разъяснения :)

person Günter Zöchbauer    schedule 12.02.2016
comment
Поскольку компонент awesome имеет объявленное входное свойство callback, callback="nameOfFuncFromAnotherComponent" свяжет строку nameOfFuncFromAnotherComponent с callback свойством компонента (а не с атрибутом). Это своего рода ярлык/специальный синтаксис Angular для констант (который мне не нравится). - person Mark Rajcok; 12.02.2016
comment
@StevenYates, callback="{{nameOfFuncFromAnotherComponent}}" не будет работать, потому что по сути он вызывает nameOfFuncFromAnotherComponent.toString() и присваивает это свойству callback. Привязка {{}} всегда присваивает строковый результат. - person Mark Rajcok; 12.02.2016
comment
@MarkRajcok большое спасибо за ваши проницательные объяснения! - person Günter Zöchbauer; 12.02.2016
comment
Что делать, если у функции есть параметры? - person MhagnumDw; 27.02.2020
comment
Нет никакой разницы. Разница в том, что когда вы позже вызываете функцию, вам нужно передать параметры. Здесь передается только ссылка на функцию. - person Günter Zöchbauer; 28.02.2020

я думаю, что использование eventEmitter в случае функции намного лучше, потому что передача функции по ссылке создаст некоторые проблемы с этим

поэтому мое предложение состоит в том, чтобы сделать следующее

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()
  }
}
person Mostafa Ahmed    schedule 29.12.2017
comment
Мне также нравится подход eventEmitter. У меня тоже была проблема с этим, но ее можно преодолеть, превратив родительскую функцию в делегат. - person Marko Živković; 20.02.2018

На самом деле нет необходимости отправлять обратный вызов в свойство @Input. Вы можете использовать #local_variable, которая предоставляет ссылку на дочерний компонент. Таким образом, у вас будет доступ ко всем его свойствам и методам из родительского шаблона. См. документацию ng2 по компоненту взаимодействие.

person Dzenad Dedic    schedule 04.10.2016
comment
если я не ошибаюсь, он ищет обратный поток связи, где дочерний компонент вызывает метод родителя. Итак, родитель передает свою функцию дочернему. - person ABCD.ca; 03.03.2017

Для меня это решение сработало:

<cm2-component [childFunc]="myFunc.bind(this)"></cm2-component>

import { Output, EventEmitter } from '@angular/core';
export class Cm2 {
  @Input('childFunc') childFunc: Function;
  constructor() { }
  invokeMyFunc(){
    this.childFunc()
  }
}
person mirik    schedule 25.11.2019