2016-10-16 15 views
7

Uczę się Angular2, po pracy z Angular1 przez kilka lat. Tworzę składnik formularza karty kredytowej, którego głównym celem jest poznanie kilku kluczowych pojęć w Angular2. Komponent powinien obsłużyć całe formatowanie i zwrócić token Stripe poprzez wywołanie zwrotne. Zdałem sobie sprawę, że mogę obsługiwać wywołania zwrotne na dwa sposoby.Angular2 dlaczego używać @Output przez @Input dla callbacków

Użycie parametru @Output

W moim komponentu I zdefiniować zmienną wyjściową i używać go tak jak w poniższym przykładzie:

export class CreditCardForm{ 
    .... 
    @Output() callback = new EventEmitter(); 
    .... 

    doCallback(){ 
     this.callback.emit({data: 123}); 
    } 
} 

// Parent view 
<credit-card-form (callback)="creditCardCallback($event)"></credit-card-form> 

Korzystanie @Input zmienną

jednak Mogę po prostu przekazać metodę wywołania zwrotnego (creditCardCallback, używaną w szablonie nadrzędnym) do zmiennej wejściowej, takiej jak ta:

export class CreditCardForm{ 
    .... 
    @Input() callback; 
    .... 

    doCallback(){ 
     this.callback({data: 123}); 
    } 
} 

// Parent view 
<credit-card-form [callback]="creditCardCallback"></credit-card-form> 

Pytanie

Dlaczego miałbym używać @Output nad @Input? Co osiągam przy użyciu zmiennych @Output? O ile widzę, to tylko dodaje obciążenie, ponieważ musi korzystać z klasy EventEmitter.

Odpowiedz

7

Zawsze istnieje więcej niż jeden sposób na skórze kota. Jednak, moim zdaniem, używając @Output ma następujące zalety:

  • czytelność kodu: Łatwiej wiedzieć przepływu danych w przypadku korzystania z zalecanej styl.

  • De-sprzęgło: Na przykład, dla normalnego @Output razie w swojej ParentComponent można mieć większą elastyczność obsługi wysłanej zdarzenie:

  • Last but not least - umożliwia banana w składnia box: mów w ChildComponent masz:

@Input() creditCardValue: string; @Output() creditCardValueChange: EventEmitter<string>;

Wtedy można mieć wiążący w swojej ParentComponent łatwo dwukierunkowej:

<credit-card-form [(creditCardValue)]="creditCardVal"></credit-card-form> 
+0

Dziękuję bardzo za wspaniałą odpowiedź! To przekonuje mnie do użycia '@ Output' dla wywołań zwrotnych. Twoja odpowiedź nauczyła mnie również, że istnieje takie sformułowanie jak "banan w składni pudełkowej", co prowadzi do zabawnych zdjęć podczas Googling :) –

+0

Zakładam też, że ponieważ z '@ Wyjście' używasz * Message Coupling * as przeciwieństwie do * External Coupling * z '@ Input'. Więc jeśli w niektórych przypadkach parametr '@ Input' jest niezdefiniowany w elemencie potomnym (nie ma rodzica?), To nie musisz się martwić o" this.callback && this.callback.call (...) "lub Metody 'noOp'. Ale mogę ** tylko ** kiedykolwiek zobaczyć użycie '@ Output' dla emisji zdarzeń - * ale myślę, że jego zły projekt definiuje twoje typy zdarzeń w skali komponentów, w przeciwieństwie do App-Scale; stworzy entropię dla twojej aplikacji i jej inżynierów *. – Cody

+0

Dzięki Harry! Po prostu zdziwiony, bo szukałem dla niego exaclty. Mój mały problem polega na tym, jak przejść z tego miejsca do swojego ładniejszego stylu? gtamborero

-1

IMHO, @Output jest ogromny projekt wada, ponieważ nie można reagować na skutek lub manipulowania nim. Przykładem tej wady jest kliknięcie przycisku. Po kliknięciu przycisk powinien być wyłączony w 99% przypadków, gdy akcja ma miejsce. Po wykonaniu akcji przycisk powinien zostać ponownie włączony. To jest coś, co chcesz obsłużyć w samym elemencie, a nie w elemencie nadrzędnym. Dzięki @Output nie możesz tego zrobić. Używając funkcji działania jako @Input, możesz to zrobić! A jeśli twoja funkcja zwraca Zwiastun lub obietnicę, możesz łatwo na nią czekać. Stworzenie niestandardowej dyrektywy, która obsługuje to wyłączanie, jest łatwe, a zatem można użyć [kliknięcia] wszędzie i zachowa się w ten sposób.

EDIT: Nie mówię @Output nie ma to zastosowania, ale nie dla działań trzeba czekać na itp .... nazywania @Input s dobre, wyjaśnia również przepływ, jak onDelete etc ...

+0

Nie jestem zwolenniczką semantyki i osobiście wolę oddzwanianie w stylu reakcji, ale aby odpowiedzieć konkretnie na twoje obawy, nie ma powodu, dla którego twoje wydarzenie źródłowe musi bezpośrednio odwoływać się do emitera. Sprawdź przykład dokumentu tutaj: https://angular.io/guide/component-interaction#parent-listens-for-child-event. Komponent potomny łączy zdarzenie kliknięcia z funkcją modułu obsługi lokalnie dla elementu potomnego. Dziecko z kolei nazywa "emitenta" emiterem. Byłoby to z pewnością dobre miejsce do dodania każdego rodzaju sprawdzania poprawności, jakie można sobie wyobrazić, aby zwielokrotnić propagację zdarzenia. – FLGMwt

+0

Tak, prawda, ale nie można kontrolować wyniku funkcji. Zawsze wprowadzam działania, które są funkcjami, do komponentu, więc komponent może je wykonywać, ale nie musi wiedzieć, co dokładnie zostanie zrobione. Takie działania zwracają obserwowalne, ponieważ może być wykonywana czynność asynchroniczna. Potrzebujemy więc sposobu na wyłączenie przycisku itp. ..... na podstawie stanu akcji, a nie można tego zrobić z wyjściem. Z wyjściem zawsze musisz przechowywać vary na komponencie, aby to zrobić, z Input i [click], możesz mieć to w dyrektywie, aby obsłużyć to za ciebie. –

Powiązane problemy