Mam komponent nadrzędny, który trafia na serwer i pobiera obiekt:
// parent component
@Component({
selector : 'node-display',
template : `
<router-outlet [node]="node"></router-outlet>
`
})
export class NodeDisplayComponent implements OnInit {
node: Node;
ngOnInit(): void {
this.nodeService.getNode(path)
.subscribe(
node => {
this.node = node;
},
err => {
console.log(err);
}
);
}
I na jednym z kilku ekranów dla dzieci:
export class ChildDisplay implements OnInit{
@Input()
node: Node;
ngOnInit(): void {
console.log(this.node);
}
}
Nie wygląda na to, że mogę po prostu wstrzyknąć dane do router-outlet
. Wygląda na to, że pojawia się błąd w konsoli internetowej:
Can't bind to 'node' since it isn't a known property of 'router-outlet'.
To trochę ma sens, ale jak mam to zrobić:
- Czy pobrać dane „węzła” z serwera z komponentu nadrzędnego?
- Czy przekazać dane pobrane z serwera do gniazda routera podrzędnego?
Wygląda na to, że nie router-outlets
działa w ten sam sposób.
node
gdzie jest jako typ,string
i wydaje się, że nie działa lub robię coś źleElementRef
ze zdarzenia z gniazda routera, aby użyć go do ustawienia identyfikatora, ale nie wiem na pamięć, czy i jak to zrobić (tylko na moim telefonie)Odpowiedź Günters jest świetna, chcę tylko wskazać inny sposób bez używania Observables.
Tutaj jednak musimy pamiętać, że te obiekty są przekazywane przez referencje, więc jeśli chcesz wykonać jakąś pracę na obiekcie w dziecku i nie wpływać na obiekt nadrzędny, sugerowałbym użycie rozwiązania Günthera. Ale jeśli nie ma to znaczenia, a nawet jest pożądanym zachowaniem , sugerowałbym następujące.
@Injectable() export class SharedService { sharedNode = { // properties }; }
W swoim rodzicu możesz przypisać wartość:
this.sharedService.sharedNode = this.node;
A w swoich dzieciach (ORAZ rodzicach) wstrzyknij udostępnioną usługę do konstruktora. Pamiętaj, aby zapewnić usługę na poziomie tablicy dostawców, jeśli chcesz, aby usługa pojedyncza obejmowała wszystkie składniki w tym module. Alternatywnie, dodaj usługę w tablicy agentow w dominującej jedynie , wtedy rodzic i dziecko będą dzielić tę samą instancję usługi.
node: Node; ngOnInit() { this.node = this.sharedService.sharedNode; }
I jak uprzejmie wskazał newman,
this.sharedService.sharedNode
w szablonie html lub getterze możesz też mieć :get sharedNode(){ return this.sharedService.sharedNode; }
źródło
Tak, możesz ustawić wejścia komponentów wyświetlanych przez gniazda routera . Niestety, musisz to zrobić programowo, jak wspomniano w innych odpowiedziach. Jest to duże zastrzeżenie, gdy w grę wchodzą obserwowalne (opisane poniżej).
Oto jak:
(1) Podłącz do
activate
zdarzenia gniazda routera w szablonie nadrzędnym:(2) Przełącz się do pliku maszynopisu rodzica i ustaw programowo dane wejściowe komponentu podrzędnego za każdym razem, gdy są aktywowane:
Gotowe.
Jednak powyższa wersja
onOutletLoaded
jest uproszczona dla przejrzystości. Działa tylko wtedy, gdy możesz zagwarantować, że wszystkie komponenty podrzędne mają dokładnie te same dane wejściowe, które przypisujesz. Jeśli masz komponenty z różnymi danymi wejściowymi, użyj osłon typów:Dlaczego ta metoda może być preferowana w stosunku do metody serwisowej?
Ani ta metoda, ani metoda usługi nie są „właściwą drogą” do komunikacji z komponentami potomnymi (obie metody odchodzą od czystego wiązania szablonu), więc musisz tylko zdecydować, który sposób jest bardziej odpowiedni dla projektu.
Jednak ta metoda pozwala uniknąć ścisłego powiązania związanego z podejściem „stwórz usługę dla komunikacji” (tj. Rodzic potrzebuje usługi, a wszystkie dzieci potrzebują usługi, co sprawia, że dzieci nie nadają się do użytku gdzie indziej). Zwykle preferowane jest odsprzęganie.
W wielu przypadkach ta metoda wydaje się również bliższa „drodze kątowej”, ponieważ możesz kontynuować przekazywanie danych do komponentów podrzędnych przez @Inputs (to jest część odsprzęgająca - umożliwia to ponowne wykorzystanie w innym miejscu). Jest to również dobre rozwiązanie dla już istniejących lub komponentów innych firm, których nie chcesz lub nie możesz ściśle połączyć z twoją usługą.
Z drugiej strony może wydawać się mniej kątowy, gdy ...
Caveat
Ograniczeniem związanym z tą metodą jest to, że ponieważ przekazujesz dane w pliku maszynopisu, nie masz już możliwości używania wzorca potoku asynchronicznego używanego w szablonach (np.
{{ myObservable$ | async }}
) Do automagicznego używania i przekazywania obserwowalnych danych do komponentów potomnych.Zamiast tego musisz skonfigurować coś, aby uzyskać bieżące obserwowalne wartości za każdym razem, gdy
onChildLoaded
wywoływana jest funkcja. Prawdopodobnie będzie to również wymagało porzucenia funkcji komponentu nadrzędnegoonDestroy
. Nie jest to nic niezwykłego, często zdarzają się przypadki, w których trzeba to zrobić, na przykład gdy używasz obserwowalnego, który nawet nie dociera do szablonu.źródło
Usługa:
Składnik:
źródło
Istnieją 3 sposoby przekazywania danych od rodzica do dzieci
Przez Children Router Resolver, jeśli musisz odbierać różne dane
Poprzez Parent Router Resolver, jeśli musisz otrzymać te same dane od rodzica
Uwaga 1: Możesz przeczytać o resolwerze tutaj . Jest też przykład resolwera i jak zarejestrować przelicznik w module, a następnie pobrać dane z resolwera do komponentu. Rejestracja resolvera jest taka sama dla rodzica i dziecka.
Uwaga 2: Możesz przeczytać o ActivatedRoute tutaj, aby móc pobrać dane z routera
źródło
Podążając za tym pytaniem, w Angular 7.2 możesz przekazywać dane od rodzica do dziecka przy użyciu stanu historii. Więc możesz zrobić coś takiego
Ale uważaj, aby być konsekwentnym. Na przykład, przypuśćmy, że chcesz wyświetlić listę na lewym pasku bocznym, a szczegóły wybranego elementu po prawej stronie za pomocą gniazda routera. Coś jak:
Pozycja 1 (x) | ..............................................
Pozycja 2 (x) | ...... Szczegóły wybranego elementu .......
Pozycja 3 (x) | ..............................................
Pozycja 4 (x) | ..............................................
Teraz załóżmy, że już kliknąłeś niektóre elementy. Kliknięcie przycisków Wstecz przeglądarki spowoduje wyświetlenie szczegółów z poprzedniej pozycji. Ale co, jeśli w międzyczasie kliknąłeś (x) i usunąłeś ten element z listy? Następnie wykonanie kliknięcia wstecz spowoduje wyświetlenie szczegółów usuniętej pozycji.
źródło