AngularJS имеет параметры &, где вы можете передать обратный вызов в директиву (например, способ обратных вызовов AngularJS . Можно ли передать обратный вызов как @Input
для углового компонента (что-то вроде ниже)? Если нет, то что было бы ближе всего к тому, что AngularJS делает?
@Component({
selector: 'suggestion-menu',
providers: [SuggestService],
template: `
<div (mousedown)="suggestionWasClicked(suggestion)">
</div>`,
changeDetection: ChangeDetectionStrategy.Default
})
export class SuggestionMenuComponent {
@Input() callback: Function;
suggestionWasClicked(clickedEntry: SomeModel): void {
this.callback(clickedEntry, this.query);
}
}
<suggestion-menu callback="insertSuggestion">
</suggestion-menu>
angularjs
angular
typescript
Михаил Михайлидис
источник
источник
@Input
предложенный способ сделал мой код спагетти и не простым в обслуживании.@Output
Это гораздо более естественный способ делать то, что я хочу. В результате я изменил принятый ответОтветы:
Я думаю, что это плохое решение. Если вы хотите передать функцию в компонент
@Input()
,@Output()
декоратор - это то, что вы ищете.источник
@Output
иEventEmitter
. Итак, вот документация Angular для @Output для тех, кто заинтересован.ОБНОВИТЬ
Этот ответ был представлен, когда Angular 2 еще находился в альфа-версии, и многие функции были недоступны / недокументированы. Хотя приведенное ниже будет работать, этот метод полностью устарел. Я сильно рекомендую принятый ответ ниже.
Оригинальный ответ
Да, на самом деле это так, однако вы захотите убедиться, что это правильно. Для этого я использовал свойство, гарантирующее то,
this
что я хочу.источник
Parent -> Child
ngOnInit
я бы просто использовать:this.theCallback = this.theCallback.bind(this)
а затем вы можете передатьtheCallback
вместоtheBoundCallback
.Альтернативу ответу SnareChops дал.
Вы можете использовать .bind (this) в своем шаблоне, чтобы получить тот же эффект. Это может быть не так чисто, но это экономит пару строк. Я в настоящее время на угловой 2.4.0
источник
@Input
же, код становится спагетти и использует@Output
результаты в более естественном / незапутанном процессеВ некоторых случаях может потребоваться выполнение бизнес-логики родительским компонентом. В приведенном ниже примере у нас есть дочерний компонент, который отображает строку таблицы в зависимости от логики, предоставленной родительским компонентом:
Итак, я хотел продемонстрировать 2 вещи здесь:
источник
.bind(this)
[getRowColor]="getColor"
а не[getRowColor]="getColor()"
;-)В качестве примера, я использую модальное окно входа в систему, где модальное окно является родителем, форма входа в систему является дочерним, а кнопка входа вызывает функцию закрытия модального родителя.
Родительский модал содержит функцию закрытия модального режима. Этот родительский элемент передает функцию close дочернему компоненту login.
После того, как дочерний компонент входа в систему отправляет форму входа в систему, он закрывает родительский модальный режим с помощью функции обратного вызова родителя.
источник
Альтернатива ответу Максу Фалу.
Вы можете определить функцию обратного вызова как функцию стрелки в родительском компоненте, так что вам не нужно будет связывать это.
источник
Передача метода с аргументом, используя .bind внутри шаблона
источник
Используйте наблюдаемый шаблон. Вы можете поместить значение Observable (не Subject) во входной параметр и управлять им из родительского компонента. Вам не нужна функция обратного вызова.
Смотрите пример: https://stackoverflow.com/a/49662611/4604351
источник
Еще одна альтернатива.
ОП спросил способ использования обратного вызова. В этом случае он имел в виду конкретно функцию, которая обрабатывает событие (в его примере: событие щелчка), которое должно рассматриваться как принятый ответ от @serginho: with
@Output
иEventEmitter
.Однако существует разница между обратным вызовом и событием: с помощью обратного вызова ваш дочерний компонент может получить некоторую обратную связь или информацию от родителя, но только событие может сообщить, что что-то произошло, не ожидая никакой обратной связи.
Есть случаи, когда необходима обратная связь, напр. получить цвет или список элементов, которые компонент должен обработать. Вы можете использовать связанные функции, как предлагали некоторые ответы, или вы можете использовать интерфейсы (это всегда мое предпочтение).
пример
Предположим, у вас есть общий компонент, работающий со списком элементов {id, name}, который вы хотите использовать со всеми таблицами базы данных, в которых есть эти поля. Этот компонент должен:
Дочерний компонент
При обычном связывании нам понадобятся 1
@Input()
и 3@Output()
параметра (но без обратной связи с родителем). Ex.<list-ctrl [items]="list" (itemClicked)="click($event)" (itemRemoved)="removeItem($event)" (loadNextPage)="load($event)" ...>
Но для создания интерфейса нам понадобится только одно@Input()
:Родительский компонент
Теперь мы можем использовать компонент list в родительском элементе.
Обратите внимание, что
<list-ctrl>
получаетthis
(родительский компонент) как объект обратного вызова. Еще одно преимущество заключается в том, что отправка родительского экземпляра не требуется, это может быть служба или любой объект, который реализует интерфейс, если это позволяет ваш сценарий использования.Полный пример этого стекаблита .
источник
Текущий ответ может быть упрощен до ...
источник
.bind(this)
этогоthis
внутри будет обратный вызов,window
который может не иметь значения в зависимости от вашего варианта использования. Однако, если у вас естьthis
обратный вызов вообще, то.bind(this)
это необходимо. Если нет, то эта упрощенная версия - путь.this
внутри функции обратного вызова. Это просто ошибка.