AngularJS ma parametry i, w których można przekazać wywołanie zwrotne do dyrektywy (np. Sposób wywołania zwrotnego AngularJS . Czy możliwe jest przekazanie wywołania zwrotnego jako @Input
dla komponentu Angular (coś takiego jak poniżej)? Jeśli nie, co byłoby najbliższe temu AngularJS robi?
@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
Michail Michailidis
źródło
źródło
@Input
sposób zasugerował, że mój kod spagetti i nie jest łatwy w utrzymaniu ..@Output
s są znacznie bardziej naturalnym sposobem robienia tego, co chcę. W rezultacie zmieniłem przyjętą odpowiedźOdpowiedzi:
Myślę, że to złe rozwiązanie. Jeśli chcesz przekazać funkcję do komponentu
@Input()
,@Output()
dekorator jest tym, czego szukasz.źródło
@Output
iEventEmitter
. Oto dokumentacja Angular dla @Output dla zainteresowanych.AKTUALIZACJA
Ta odpowiedź została przesłana, gdy Angular 2 był jeszcze w wersji alfa, a wiele funkcji było niedostępnych / nieudokumentowanych. Chociaż poniższe funkcje będą nadal działać, ta metoda jest teraz całkowicie nieaktualna. Ja zdecydowanie polecam zaakceptowane odpowiedź na niżej.
Oryginalna odpowiedź
Tak, w rzeczywistości tak jest, jednak należy upewnić się, że zakres jest prawidłowy. W tym celu skorzystałem z właściwości, aby upewnić się, że
this
oznacza to, czego chcę.źródło
Parent -> Child
ngOnInit
Chciałbym po prostu użyć:this.theCallback = this.theCallback.bind(this)
i wtedy możesz przekazać dalejtheCallback
zamiasttheBoundCallback
.Alternatywa dla odpowiedzi udzielonej przez SnareChops.
Możesz użyć .bind (this) w swoim szablonie, aby uzyskać ten sam efekt. Może nie jest tak czysty, ale oszczędza kilka linii. Obecnie używam kątowej wersji 2.4.0
źródło
@Input
powoduje, że kod staje się spaghetti, a stosowanie@Output
wyników w bardziej naturalny / nieplątany procesW niektórych przypadkach może być konieczne wykonanie logiki biznesowej przez komponent nadrzędny. W poniższym przykładzie mamy komponent potomny, który renderuje wiersz tabeli w zależności od logiki dostarczonej przez komponent nadrzędny:
Chciałem więc tutaj zademonstrować 2 rzeczy:
źródło
.bind(this)
[getRowColor]="getColor"
i nie[getRowColor]="getColor()"
;-)Jako przykład używam okna modalnego logowania, gdzie okno modalne jest nadrzędne, formularz logowania to dziecko, a przycisk logowania wywołuje funkcję zamknięcia modalnego rodzica.
Modal nadrzędny zawiera funkcję zamykania modalu. Ten rodzic przekazuje funkcję zamykania do komponentu potomnego logowania.
Po przesłaniu formularza podrzędnego logowania dziecko zamyka moduł nadrzędny za pomocą funkcji wywołania zwrotnego nadrzędnego
źródło
Alternatywa dla odpowiedzi udzielonej przez Maxa Fahla.
Możesz zdefiniować funkcję wywołania zwrotnego jako funkcję strzałki w komponencie nadrzędnym, aby nie trzeba było tego wiązać.
źródło
Przekazywanie metody z argumentem za pomocą .bind w szablonie
źródło
Użyj obserwowalnego wzoru. Możesz wstawić wartość Obserwowalną (nie Temat) do parametru wejściowego i zarządzać nią z komponentu nadrzędnego. Nie potrzebujesz funkcji oddzwaniania.
Zobacz przykład: https://stackoverflow.com/a/49662611/4604351
źródło
Kolejna alternatywa.
OP poprosił o sposób oddzwonienia. W tym przypadku odnosił się konkretnie do funkcji przetwarzającej zdarzenie (w jego przykładzie: zdarzenie kliknięcia), która powinna być traktowana jako zaakceptowana odpowiedź z @serginho: za pomocą
@Output
iEventEmitter
.Istnieje jednak różnica między wywołaniem zwrotnym a zdarzeniem: dzięki wywołaniu zwrotnemu komponent podrzędny może uzyskać informacje zwrotne lub informacje od rodzica, ale zdarzenie może tylko poinformować, że coś się wydarzyło bez oczekiwania na informację zwrotną.
Istnieją przypadki użycia, w których konieczne jest sprzężenie zwrotne, np. uzyskać kolor lub listę elementów, które komponent musi obsłużyć. Możesz użyć funkcji powiązanych, jak sugerują niektóre odpowiedzi, lub możesz użyć interfejsów (to zawsze moja preferencja).
Przykład
Załóżmy, że masz ogólny komponent, który działa na liście elementów {id, name}, których chcesz używać ze wszystkimi tabelami bazy danych zawierającymi te pola. Ten komponent powinien:
Komponent potomny
Używając normalnego wiązania potrzebowalibyśmy 1
@Input()
i 3@Output()
parametry (ale bez żadnej informacji zwrotnej od rodzica). Dawny.<list-ctrl [items]="list" (itemClicked)="click($event)" (itemRemoved)="removeItem($event)" (loadNextPage)="load($event)" ...>
, ale do utworzenia interfejsu potrzebujemy tylko jednego@Input()
:Komponent macierzysty
Teraz możemy użyć komponentu listy w elemencie nadrzędnym.
Zauważ, że
<list-ctrl>
odbierathis
(komponent nadrzędny) jako obiekt wywołania zwrotnego. Dodatkową zaletą jest to, że nie jest wymagane wysyłanie instancji nadrzędnej, może to być usługa lub dowolny obiekt implementujący interfejs, jeśli pozwala na to przypadek użycia.Kompletny przykład jest na tym stackblitz .
źródło
Obecną odpowiedź można uprościć ...
źródło
.bind(this)
tegothis
wnętrze oddzwaniania będzie,window
co może nie mieć znaczenia w zależności od przypadku użycia. Jeśli jednak w ogóle maszthis
oddzwonienie,.bind(this)
jest to konieczne. Jeśli nie, to ta uproszczona wersja jest najlepszym rozwiązaniem.this
funkcji wywołania zwrotnego. To po prostu podatne na błędy.