Czy jest możliwe, aby jeden kontroler używał innego?
Na przykład:
Ten dokument HTML po prostu drukuje wiadomość dostarczoną przez MessageCtrl
kontroler w messageCtrl.js
pliku.
<html xmlns:ng="http://angularjs.org/">
<head>
<meta charset="utf-8" />
<title>Inter Controller Communication</title>
</head>
<body>
<div ng:controller="MessageCtrl">
<p>{{message}}</p>
</div>
<!-- Angular Scripts -->
<script src="http://code.angularjs.org/angular-0.9.19.js" ng:autobind></script>
<script src="js/messageCtrl.js" type="text/javascript"></script>
</body>
</html>
Plik kontrolera zawiera następujący kod:
function MessageCtrl()
{
this.message = function() {
return "The current date is: " + new Date().toString();
};
}
Który po prostu drukuje bieżącą datę;
Gdybym miał dodać kolejny kontroler, DateCtrl
który wrócił do daty w określonym formacie MessageCtrl
, jak by to zrobić? Ramy DI wydają się dotyczyć XmlHttpRequests
usług i uzyskiwać do nich dostęp.
javascript
html
angularjs
BanksySan
źródło
źródło
Odpowiedzi:
Istnieje wiele sposobów komunikacji między kontrolerami.
Najlepszym rozwiązaniem jest prawdopodobnie udostępnianie usługi:
Innym sposobem jest wysłanie zdarzenia w zakresie:
W obu przypadkach możesz również komunikować się z dowolną dyrektywą.
źródło
Zobacz to skrzypce: http://jsfiddle.net/simpulton/XqDxG/
Obejrzyj także następujący film: Komunikacja między kontrolerami
HTML:
javascript:
źródło
Jeśli chcesz połączyć jeden kontroler z innym, dostępne są cztery metody
Kontroler i jego zakres mogą zostać zniszczone, ale $ rootScope pozostaje w aplikacji, dlatego bierzemy $ rootScope, ponieważ $ rootScope jest rodzicem wszystkich zakresów.
Jeśli prowadzisz komunikację między rodzicem a dzieckiem, a nawet dziecko chce komunikować się z rodzeństwem, możesz użyć programu $ broadcast
Jeśli wykonujesz komunikację między dzieckiem a rodzicem, żadne rodzeństwo nie jest powiązane, możesz użyć $ rootScope.
HTML
Kod Angularjs
W powyższej kodzie konsoli $ emit „childEmit” nie będzie wywoływał rodzeństwa podrzędnego i będzie wywoływał tylko rodzica, gdzie $ broadcast zostanie wywołany również wewnątrz rodzeństwa i rodzica. To jest miejsce, w którym występuje wydajność. preferowane, jeśli używasz komunikacji dziecko-rodzic, ponieważ pomija ona niektóre brudne kontrole.
Jest to jedna z najlepszych metod. Jeśli chcesz przeprowadzić komunikację między rodzicem a dzieckiem, w której dziecko chce komunikować się z bezpośrednim rodzicem , nie potrzebuje żadnej emisji lub emisji, ale jeśli chcesz nawiązać komunikację między rodzicem a dzieckiem, musisz użyj usługi lub $ broadcast
Na przykład HTML: -
Angularjs
Za każdym razem, gdy używasz komunikacji dziecko-rodzic, Angularjs szuka zmiennej wewnątrz dziecka, jeśli nie jest ona obecna w środku, wybierze wyświetlanie wartości w kontrolerze nadrzędnym.
AngularJS obsługuje koncepcje „oddzielania obaw” przy użyciu architektury usług. Usługi są funkcjami javascript i są odpowiedzialne za wykonywanie tylko określonych zadań, co czyni je indywidualnymi jednostkami, które można konserwować i testować .
Kod Angularjs:
Daje wyjście Hello Child World i Hello Parent World. Według dokumentów Angular usług Singletons - Każdy komponent zależny od usługi otrzymuje odniesienie do pojedynczego wystąpienia wygenerowanego przez fabrykę usług .
Ta metoda pobiera zakres () z elementu za pomocą swojej metody Id / unique class.angular.element () zwraca element, a scope () daje zmienną $ scope innej zmiennej przy użyciu zmiennej $ scope jednego kontrolera wewnątrz drugiego, nie jest dobrą praktyką.
HTML: -
Angularjs: -
W powyższym kodzie kontrolery wyświetlają swoją wartość na HTML, a kiedy klikniesz tekst, otrzymasz odpowiednio wartości w konsoli. Jeśli klikniesz na zakres kontrolerów nadrzędnych, przeglądarka konsoluje wartość child i viceversa.
źródło
Oto jednostronicowy przykład dwóch kontrolerów współdzielących dane usługi:
Również tutaj: https://gist.github.com/3595424
źródło
theService
aktualizacjething.x
, to ta zmiana automatycznie sugeruje <wejście> wFirstCtrl
iSecondCtrl
, prawda? I można również zmienićthing.x
bezpośrednio za pomocą jednego z dwóch <wejść> (prawda?).Jeśli chcesz emitować i transmitować zdarzenia w celu udostępniania danych lub funkcji połączeń między kontrolerami , spójrz na ten link : i sprawdź odpowiedź przez
zbynour
(odpowiedz z maksymalną liczbą głosów). Cytuję jego odpowiedź !!!Jeśli zakres firstCtrl jest nadrzędny dla zakresu secondCtrl, kod powinien działać, zastępując $ emit przez $ broadcast w firstCtrl:
Jeśli pomiędzy Twoimi zasięgami nie ma relacji rodzic-dziecko, możesz wstrzyknąć $ rootScope do kontrolera i transmitować zdarzenie do wszystkich zakresów potomnych (tj. Także secondCtrl).
Wreszcie, gdy trzeba wysłać zdarzenie z kontrolera potomnego w zakresy w górę, możesz użyć $ scope. $ Emit. Jeśli zakres firstCtrl jest rodzicem zakresu secondCtrl:
źródło
Dwa kolejne skrzypce: (podejście nieobsługowe)
1) Dla kontrolera
$scope
nadrzędnego i podrzędnego - Wykorzystanie nadrzędnego kontrolera do emisji / emisji zdarzeń. http://jsfiddle.net/laan_sachin/jnj6y/2) Korzystanie
$rootScope
z niepowiązanych kontrolerów. http://jsfiddle.net/VxafF/źródło
W rzeczywistości użycie emisji i emisji jest nieefektywne, ponieważ zdarzenie przesuwa się w górę iw dół hierarchii zasięgu, co może łatwo zmienić się w butelkę wydajności dla złożonej aplikacji.
Sugerowałbym skorzystanie z usługi. Oto jak niedawno wdrożyłem go w jednym z moich projektów - https://gist.github.com/3384419 .
Podstawowy pomysł - zarejestruj autobus sub-pub / event jako usługę. Następnie wstrzyknij tę magistralę zdarzeń tam, gdzie trzeba subskrybować lub opublikować wydarzenia / tematy.
źródło
Znam również tę drogę.
Ale nie używam go zbyt często, ponieważ nie lubię używać selektorów jQuery w kodzie kątowym.
źródło
Istnieje metoda niezależna od usług
$broadcast
lub$emit
. Nie jest to odpowiednie we wszystkich przypadkach, ale jeśli masz 2 powiązane kontrolery, które można przekształcić w dyrektywy, możesz skorzystać zrequire
opcji w definicji dyrektywy. Jest to najprawdopodobniej sposób, w jaki komunikują się ngModel i ngForm. Możesz użyć tego do komunikacji między kontrolerami dyrektywy, które są zagnieżdżone lub w tym samym elemencie.W przypadku sytuacji rodzic / dziecko użycie byłoby następujące:
I główne punkty, aby to działa: W dyrektywie macierzystego z metody nazywać, należy je określić na
this
(nie$scope
):W definicji dyrektywy podrzędnej można użyć tej
require
opcji, aby nadrzędny kontroler został przekazany do funkcji dowiązania (aby można było wywoływać na niej funkcje zscope
dyrektywy podrzędnej.Powyższe można zobaczyć na stronie http://plnkr.co/edit/poeq460VmQER8Gl9w8Oz?p=preview
Dyrektywa dotycząca rodzeństwa jest stosowana podobnie, ale obie dyrektywy dotyczą tego samego elementu:
Używane, tworząc metodę na
directive1
:A w dyrektywie2 można to wywołać za pomocą
require
opcji, która powoduje przekazanie kontrolera siblingController do funkcji link:Można to zobaczyć na stronie http://plnkr.co/edit/MUD2snf9zvadfnDXq85w?p=preview .
Zastosowania tego?
Rodzic: każdy przypadek, w którym elementy potomne muszą się „zarejestrować” u rodzica. Podobnie jak związek między ngModel i ngForm. Mogą dodać pewne zachowanie, które może wpływać na modele. Możesz mieć również coś opartego wyłącznie na DOM, w którym element nadrzędny musi zarządzać pozycjami niektórych dzieci, powiedzmy, aby zarządzać przewijaniem lub reagować na nie.
Rodzeństwo: zezwalanie na modyfikację zachowania dyrektywy. ngModel to klasyczny przypadek dodawania parserów / sprawdzania poprawności do użycia ngModel na wejściach.
źródło
Nie wiem, czy jest to niezgodne ze standardami, ale jeśli masz wszystkie kontrolery w tym samym pliku, możesz zrobić coś takiego:
Jak widać wskaźnikiCtrl wywołuje funkcje updateChart pozostałych kontrolerów podczas wywoływania updateCharts.
źródło
Możesz wstrzyknąć usługę „$ controller” do kontrolera nadrzędnego (MessageCtrl), a następnie utworzyć instancję / wstrzyknąć kontroler podrzędny (DateCtrl), używając:
$scope.childController = $controller('childController', { $scope: $scope.$new() });
Teraz możesz uzyskać dostęp do danych z kontrolera podrzędnego, wywołując jego metody, ponieważ jest to usługa.
Daj mi znać, jeśli jakiś problem.
źródło
Poniżej znajduje się
publish-subscribe
podejście, które jest niezależne od Angular JS.Wyszukaj Param Controller
Kontroler wyboru wyszukiwania
Menedżer zdarzeń
Światowy
źródło
W wersji kątowej 1.5 można to zrobić, wykonując następujące czynności:
To jest element nadrzędny. W tym utworzyłem funkcję, która wypycha inny obiekt do mojej
productForms
tablicy - uwaga - to tylko mój przykład, ta funkcja może być czymkolwiek naprawdę.Teraz możemy stworzyć kolejny komponent, który będzie wykorzystywał
require
:W tym przypadku komponent potomny tworzy odwołanie do funkcji komponentu nadrzędnego,
addNewForm
która może być następnie powiązana z kodem HTML i wywołana jak każda inna funkcja.źródło