Mam ListComponent. Po kliknięciu elementu w ListComponent szczegóły tego elementu powinny zostać wyświetlone w DetailComponent. Oba są wyświetlane na ekranie w tym samym czasie, więc nie ma tu żadnego routingu.
Jak powiedzieć DetailComponent, który element w ListComponent został kliknięty?
Rozważyłem wysłanie zdarzenia do elementu nadrzędnego (AppComponent) i kazałem rodzicowi ustawić selectedItem.id na DetailComponent z @Input. Albo mógłbym skorzystać z usługi współdzielonej z obserwowalnymi subskrypcjami.
EDYCJA: Ustawienie wybranego elementu za pomocą zdarzenia + @Input nie powoduje jednak wywołania elementu DetailComponent na wypadek, gdyby trzeba było wykonać dodatkowy kod. Więc nie jestem pewien, czy to akceptowalne rozwiązanie.
Ale obie te metody wydają się o wiele bardziej złożone niż sposób robienia rzeczy w Angular 1, który był albo przez $ rootScope. $ Broadcast, albo $ scope. $ Parent. $ Broadcast.
Ponieważ wszystko w Angular 2 jest komponentem, jestem zaskoczony, że nie ma więcej informacji o komunikacji komponentów.
Czy jest inny / prostszy sposób na osiągnięcie tego?
źródło
Odpowiedzi:
Zaktualizowano do rc.4: Podczas próby przesłania danych między komponentami rodzeństwa w angular 2, najprostszym obecnie sposobem (angular.rc.4) jest wykorzystanie hierarchicznego wstrzyknięcia zależności angular2 i utworzenie usługi współdzielonej.
Oto usługa:
Teraz tutaj będzie komponent PARENT
i dwoje jego dzieci
dziecko 1
dziecko 2 (rodzeństwo)
TERAZ: Rzeczy, o których należy pamiętać podczas korzystania z tej metody.
źródło
directives
nie są już deklarowane w komponencie.W przypadku dwóch różnych komponentów (nie zagnieżdżonych komponentów, rodzic \ dziecko \ wnuk) proponuję to:
źródło
Jednym ze sposobów jest skorzystanie z usługi współdzielonej .
Jednak uważam, że poniższe rozwiązanie jest znacznie prostsze, pozwala na udostępnianie danych między dwojgiem rodzeństwa (testowałem to tylko na Angular 5 )
W swoim macierzystym szablonie komponentu:
app-sibling2.component.ts
źródło
Tutaj jest dyskusja na ten temat.
https://github.com/angular/angular.io/issues/2663
Odpowiedź Alexa J jest dobra, ale nie działa już z obecnym Angular 4 od lipca 2017 r.
A ten link plunker pokazałby, jak komunikować się między rodzeństwem za pomocą usługi współdzielonej i obserwowalnej.
https://embed.plnkr.co/P8xCEwSKgcOg07pwDrlO/
źródło
Dyrektywa może mieć sens w pewnych sytuacjach, aby „połączyć” komponenty. W rzeczywistości podłączone elementy nie muszą być nawet pełnymi komponentami, a czasami jest to lżejsze i prostsze, jeśli nie są.
Na przykład mam
Youtube Player
komponent (owijający YouTube API) i chciałem do niego kilka przycisków kontrolera. Jedynym powodem, dla którego przyciski nie są częścią mojego głównego komponentu, jest to, że znajdują się w innym miejscu DOM.W tym przypadku jest to tak naprawdę tylko komponent „rozszerzenia”, który będzie używany tylko z komponentem „nadrzędnym”. Mówię „rodzic”, ale w DOM jest to rodzeństwo - więc nazwij to, jak chcesz.
Tak jak powiedziałem, nie musi to być nawet pełny komponent, w moim przypadku to tylko
<button>
(ale może to być komponent).W kodzie HTML dla
ProductPage.component
, gdzieyoutube-player
jest oczywiście mój komponent, który otacza API YouTube.Dyrektywa podpina wszystko za mnie i nie muszę deklarować zdarzenia (kliknięcia) w kodzie HTML.
Dzięki temu dyrektywa może ładnie łączyć się z odtwarzaczem wideo bez konieczności angażowania się
ProductPage
w rolę mediatora.To pierwszy raz, kiedy to zrobiłem, więc nie jestem jeszcze pewien, jak skalowalny może być w znacznie bardziej złożonych sytuacjach. Z tego powodu jestem zadowolony i pozostawia mój HTML prosty i odpowiedzialność za wszystko odrębne.
źródło
player
. Jeśli pominę pierwszą wzmiankę o graczu, pojawi się RangeError. Jestem zdumiony, jak to ma działać._player
pola prywatnego, które reprezentuje gracza, więc tak, dostaniesz błąd, jeśli skopiujesz to dokładnie. Zaktualizuję. Przepraszam!Oto proste praktyczne wyjaśnienie: po prostu wyjaśnione tutaj
W call.service.ts
Komponent, z którego chcesz wywołać obserwowalny, aby poinformować inny komponent, że przycisk został kliknięty
Komponent, w którym chcesz wykonać akcję po kliknięciu przycisku na innym komponencie
Moje zrozumienie komunikacji komponentów jest jasne, czytając to: http://musttoknow.com/angular-4-angular-5-communicate-two-components-using-observable-subject/
źródło
Usługa współdzielona jest dobrym rozwiązaniem tego problemu. Jeśli chcesz również przechowywać informacje o aktywności, możesz dodać usługę udostępnioną do listy dostawców głównych modułów (moduł aplikacji).
Następnie możesz dostarczyć go bezpośrednio do swoich komponentów,
Dzięki usłudze Shared Service możesz użyć funkcji lub utworzyć Temat, aby zaktualizować wiele miejsc jednocześnie.
W komponencie listy możesz publikować informacje o klikniętym elemencie,
a następnie możesz pobrać te informacje do komponentu szczegółów:
Oczywiście dane udostępniane przez składnik listy mogą być dowolne. Mam nadzieję że to pomoże.
źródło
Musisz skonfigurować relację rodzic-dziecko między komponentami. Problem polega na tym, że możesz po prostu wstrzyknąć komponenty potomne do konstruktora komponentu nadrzędnego i zapisać je w zmiennej lokalnej. Zamiast tego należy zadeklarować składniki podrzędne w składniku nadrzędnym za pomocą
@ViewChild
deklaratora właściwości. Tak powinien wyglądać Twój komponent nadrzędny:https://angular.io/docs/ts/latest/api/core/index/ViewChild-var.html
https://angular.io/docs/ts/latest/cookbook/component-communication.html#parent-to-view-child
Uwaga, komponent potomny nie będzie dostępny w konstruktorze komponentu macierzystego zaraz po
ngAfterViewInit
wywołaniu zaczepu cyklu życia. Aby złapać ten haczyk, po prostu zaimplementujAfterViewInit
interfejs w swojej klasie nadrzędnej w taki sam sposób, jak zrobiłbyś to zOnInit
.Istnieją jednak inne deklaratory właściwości, jak wyjaśniono w tej notatce na blogu: http://blog.mgechev.com/2016/01/23/angular2-viewchildren-contentchildren-difference-viewproviders/
źródło
Podmioty zachowania. Napisałem o tym blog .
W tym przykładzie deklaruję zachowanie noida typu numer. To także jest obserwowalne. A jeśli „coś się wydarzy”, zmieni się to dzięki funkcji new () {}.
Tak więc w komponentach rodzeństwa jeden wywoła funkcję, aby dokonać zmiany, a drugi zostanie dotknięty tą zmianą lub odwrotnie.
Na przykład pobieram identyfikator z adresu URL i aktualizuję noid z tematu zachowania.
A z drugiej strony mogę zapytać, czy ten identyfikator jest „cokolwiek chcę”, a następnie dokonać wyboru, w moim przypadku, jeśli chcę usunąć zadanie, a tym zadaniem jest bieżący adres URL, musi mnie przekierować do domu:
źródło
Nie jest to dokładnie to, czego chcesz, ale na pewno ci pomoże
Jestem zaskoczony, że nie ma więcej informacji na temat komunikacji komponentów <=> rozważ ten samouczek autorstwa angualr2
W przypadku komunikacji z komponentami rodzeństwa proponuję skorzystać z
sharedService
. Dostępne są jednak również inne opcje.Więcej kodu znajdziesz w linku u góry.
Edycja: To jest bardzo małe demo. Wspomniałeś już, że próbowałeś już z
sharedService
. Dlatego prosimy o rozważenie tego samouczka autorstwa angualr2, aby uzyskać więcej informacji.źródło
Przekazywałem metody ustawiające z elementu nadrzędnego do jednego z jego elementów podrzędnych za pośrednictwem powiązania, wywołując tę metodę z danymi ze składnika podrzędnego, co oznacza, że składnik nadrzędny jest aktualizowany i może następnie zaktualizować drugi składnik podrzędny o nowe dane. Wymaga jednak wiązania „this” lub użycia funkcji strzałki.
Ma to tę zaletę, że dzieci nie są ze sobą tak połączone, ponieważ nie potrzebują specjalnej wspólnej usługi.
Nie jestem całkowicie pewien, czy jest to najlepsza praktyka, byłoby interesujące usłyszeć opinie innych na ten temat.
źródło