Jak mogę wysłać mój $scope
obiekt z jednego kontrolera do drugiego za pomocą .$emit
i .$on
metod?
function firstCtrl($scope) {
$scope.$emit('someEvent', [1,2,3]);
}
function secondCtrl($scope) {
$scope.$on('someEvent', function(mass) { console.log(mass); });
}
Nie działa tak, jak myślę, że powinno. Jak działa $emit
i $on
działa?
javascript
angularjs
Paul Kononenko
źródło
źródło
$rootScope
do nadawania / emitowania, gdy można tego uniknąć.Odpowiedzi:
Przede wszystkim relacja zakresu rodzic-dziecko ma znaczenie. Masz dwie możliwości wyemitowania jakiegoś zdarzenia:
$broadcast
- wysyła zdarzenie w dół do wszystkich zakresów potomnych,$emit
- wywołuje zdarzenie w górę poprzez hierarchię zasięgu.Nic nie wiem na temat relacji kontrolerów (zakresów), ale istnieje kilka opcji:
Jeśli zakres
firstCtrl
jest dominującym wsecondCtrl
zakresie, Twój kod powinien działać przez zastąpienie$emit
przez$broadcast
wfirstCtrl
:W przypadku braku relacji rodzic-dziecko między twoimi zakresami, możesz wstrzyknąć
$rootScope
do kontrolera i transmitować zdarzenie do wszystkich zakresów potomnych (tj. RównieżsecondCtrl
).Wreszcie, gdy trzeba wysłać zdarzenie z kontrolera podrzędnego do zakresów w górę, możesz użyć
$scope.$emit
. Jeśli zakresfirstCtrl
jest rodzicemsecondCtrl
zakresu:źródło
$rootScope
do swojej usługi i transmitować wydarzenie z usługi.$rootScope
- ale chcę wiedzieć, że jeśli wyemituję zdarzenie z usługi (poza$rootScope
), to zdarzenie będzie nadal przenikać$rootScope
; PONIEWAŻ, jeśli$broadcast
przenika W DÓŁ hierarchii i$emit
przenosi W GÓRĘ - co dzieje się MIĘDZY „UP” i „DOWN” - ponieważ nadawca / emiter jest również odbiornikiem (?). Co jeśli chcę, aby wydarzenie było ciche dla WSZYSTKICH zakresów „W GÓRĘ” i WSZYSTKICH „W DÓŁ”, ale było „słyszalne” tylko na tym samym poziomie co dyspozytor?Dodatkowo zasugerowałbym czwartą opcję jako lepszą alternatywę dla proponowanych opcji @zbynour.
Użyj
$rootScope.$emit
raczej niż$rootScope.$broadcast
niezależnie od relacji między nadawaniem a kontrolerem odbierającym. W ten sposób wydarzenie pozostaje w obrębie zbioru,$rootScope.$$listeners
podczas$rootScope.$broadcast
gdy wydarzenie rozprzestrzenia się na wszystkie zakresy dzieci, z których większość i tak prawdopodobnie nie będzie słuchaczami tego wydarzenia. I oczywiście na końcu kontrolera odbierającego po prostu używasz$rootScope.$on
.W przypadku tej opcji należy pamiętać o zniszczeniu nasłuchiwania rootScope kontrolera:
źródło
$rootScope
wstrzyknięcia do kontrolerów (co na ogół nie jest potrzebne). Ale na pewno inna opcja, dzięki!Możesz wysłać dowolny obiekt w hierarchii swojej aplikacji, w tym $ scope .
Oto krótki pomysł na temat sposobu nadawania i emitowania .
Zwróć uwagę na poniższe węzły; wszystkie zagnieżdżone w węźle 3. Korzystasz z rozgłaszania i emisji, gdy masz taki scenariusz.
Uwaga: Liczba każdego węzła w tym przykładzie jest dowolna; z łatwością może być numerem jeden; numer dwa; lub nawet liczba 1348. Każda liczba jest tylko identyfikatorem dla tego przykładu. Celem tego przykładu jest pokazanie zagnieżdżenia kontrolerów / dyrektyw Angular.
Sprawdź to drzewo. Jak odpowiesz na następujące pytania?
Uwaga: istnieją inne sposoby odpowiedzi na te pytania, ale tutaj omówimy transmisję i emisję . Ponadto, czytając poniższy tekst, załóż, że każdy numer ma własny plik (dyrektywę, kontroler) np. One.js, two.js, three.js.
Jak węzeł 1 przemawia do węzła 3 ?
W pliku one.js
W pliku three.js - najwyższy węzeł do wszystkich węzłów potomnych potrzebnych do komunikacji.
Jak węzeł 2 mówi do węzła 3?
W pliku two.js
W pliku three.js - najwyższy węzeł do wszystkich węzłów potomnych potrzebnych do komunikacji.
Jak węzeł 3 przemawia do węzła 1 i / lub węzła 2?
W pliku three.js - najwyższy węzeł do wszystkich węzłów potomnych potrzebnych do komunikacji.
W pliku one.js && two.js, w zależności od tego, który plik chcesz przechwycić, lub jedno i drugie.
Jak węzeł 2 przemawia do węzła 1?
W pliku two.js
W pliku three.js - najwyższy węzeł do wszystkich węzłów potomnych potrzebnych do komunikacji.
W pliku one.js
JEDNAK
Oto co lubię robić.
W górnej węzeł nadrzędny ( 3 w tym przypadku ...), którym może być kontroler rodzic ...
Tak więc w pliku three.js
Teraz w dowolnym węźle podrzędnym wystarczy tylko $ wyemitować wiadomość lub złapać ją za pomocą $ on .
UWAGA: Zwykle dość łatwo jest rozmawiać krzyżowo w jednej zagnieżdżonej ścieżce bez użycia $ emit , $ broadcast lub $ on , co oznacza, że większość przypadków użycia występuje, gdy próbujesz zmusić węzeł 1 do komunikacji z węzłem 2 lub odwrotnie.
Jak węzeł 2 przemawia do węzła 1?
W pliku two.js
W pliku three.js - najwyższy węzeł do wszystkich węzłów potomnych potrzebnych do komunikacji.
Już sobie z tym poradziliśmy, pamiętasz?
W pliku one.js
Nadal będziesz musiał użyć $ on dla każdej konkretnej wartości, którą chcesz złapać, ale teraz możesz tworzyć, co chcesz w dowolnym z węzłów, nie martwiąc się o to, jak przekazać wiadomość przez lukę węzła nadrzędnego, gdy łapiemy i transmitujemy ogólne pushChangesToAllNodes .
Mam nadzieję że to pomoże...
źródło
The event life cycle starts at the scope on which $broadcast was called. All listeners listening for name event on this scope get notified.
więc (podobnie jak ja) dostaniesz nieskończoną pętlę, jeśli zaimplementujesz ctrl1 rozmawiając z ctrl2 za pomocą$on('x', function(e, data) { $broadcast('x', data) })
na ctrl3. Będziesz potrzebował tych linii przed emisją;if (e.targetScope.$id === $scope.$id) { return; }
Aby wysłać
$scope object
z jednego kontrolera do drugiego, omówię$rootScope.$broadcast
i$rootScope.$emit
tutaj, ponieważ są one najczęściej używane.Przypadek 1 :
$ rootScope. $ broadcast: -
$rootScope
słuchacz nie jest automatycznie niszczony. Musisz go zniszczyć za pomocą$destroy
. Lepiej jest używać,$scope.$on
gdy nasłuchiwacze$scope
są niszczone automatycznie, tj. Jak tylko zniszczony jest zakres $.Lub,
Przypadek 2:
$ rootScope. $ emit:
Główną różnicą w $ emit i $ broadcast jest to, że zdarzenie $ rootScope. $ Emit musi być nasłuchiwane za pomocą $ rootScope. $ On, ponieważ emitowane zdarzenie nigdy nie przechodzi przez drzewo zasięgu. .
W tym przypadku musisz także zniszczyć słuchacza, tak jak w przypadku emisji $.
Edytować:
Edycja 2 :
źródło
Musisz użyć $ rootScope, aby wysyłać i rejestrować zdarzenia między kontrolerami w tej samej aplikacji. Wstrzyknąć kontrolerom zależność $ rootScope. Oto działający przykład.
Zdarzenia połączone z obiektem $ scope działają po prostu w kontrolerze właściciela. Komunikacja między kontrolerami odbywa się za pomocą $ rootScope lub Services.
źródło
Możesz zadzwonić do serwisu z kontrolera, który zwraca obietnicę, a następnie użyć go w kontrolerze. I dalej wykorzystuj
$emit
lub$broadcast
informuj o tym innych kontrolerów. W moim przypadku musiałem wykonywać połączenia http za pośrednictwem mojej usługi, więc zrobiłem coś takiego:i moja usługa wygląda tak
źródło
To moja funkcja:
źródło
źródło
Zakresów można używać do propagowania, wysyłania zdarzeń do potomków zakresu lub rodzica.
$ emit - propaguje zdarzenie do rodzica. $ broadcast - rozpowszechnia wydarzenie wśród dzieci. $ on - metoda nasłuchiwania zdarzeń, propagowana przez $ emit i $ broadcast.
przykładowy index.html :
przykład app.js :
Tutaj możesz przetestować kod: http://jsfiddle.net/zp6v0rut/41/
źródło
Poniższy kod pokazuje dwa kontrolery podrzędne, z których zdarzenia są wysyłane w górę do kontrolera nadrzędnego (rootScope)
http://jsfiddle.net/shushanthp/zp6v0rut/
źródło
Zgodnie z dokumentacją zdarzenia angularjs koniec odbiorczy powinien zawierać argumenty o strukturze podobnej do
@params
- Zdarzenie {Object} to obiekt zdarzenia zawierający informacje o zdarzeniu
- Argumenty {Object} przekazywane przez odbiorcę (pamiętaj, że może to być tylko jeden, dlatego lepiej zawsze wysyłać obiekt słownika)
$scope.$on('fooEvent', function (event, args) { console.log(args) });
Z twojego koduRównież jeśli próbujesz uzyskać udostępnioną informację dla różnych kontrolerów, istnieje inny sposób, aby to osiągnąć, a mianowicie usługi kątowe. Ponieważ usługi są singletonami, informacje można przechowywać i pobierać między kontrolerami. Po prostu utwórz getter i ustawiaj funkcje w tej usłudze, ujawniaj te funkcje, twórz zmienne globalne w usłudze i używaj ich do przechowywania informacji
źródło
Najłatwiejszy sposób:
źródło