Mam dwa kontrolery Angular:
function Ctrl1($scope) {
$scope.prop1 = "First";
}
function Ctrl2($scope) {
$scope.prop2 = "Second";
$scope.both = Ctrl1.prop1 + $scope.prop2; //This is what I would like to do ideally
}
Nie mogę użyć w Ctrl1
środku, Ctrl2
ponieważ jest niezdefiniowany. Jeśli jednak spróbuję przekazać to tak…
function Ctrl2($scope, Ctrl1) {
$scope.prop2 = "Second";
$scope.both = Ctrl1.prop1 + $scope.prop2; //This is what I would like to do ideally
}
Dostaję błąd Czy ktoś wie jak to zrobić?
Robić
Ctrl2.prototype = new Ctrl1();
Również się nie udaje.
UWAGA: Te kontrolery nie są zagnieżdżone w sobie.
javascript
angularjs
angularjs-controller
dopatraman
źródło
źródło
Odpowiedzi:
Jednym ze sposobów udostępniania zmiennych między wieloma kontrolerami jest utworzenie usługi i wstrzyknięcie jej do dowolnego kontrolera, w którym chcesz z niej korzystać.
Przykład prostej usługi:
Korzystanie z usługi w kontrolerze:
Jest to bardzo ładnie opisane na tym blogu (lekcja 2 i dalsze).
Przekonałem się, że jeśli chcesz powiązać te właściwości na wielu kontrolerach, działa to lepiej, jeśli powiążesz z właściwością obiektu zamiast typu pierwotnego (wartość logiczna, łańcuch, liczba), aby zachować powiązane odniesienie.
Przykład:
var property = { Property1: 'First' };
zamiastvar property = 'First';
.AKTUALIZACJA: Aby (miejmy nadzieję) wyjaśnić tutaj, jest skrzypce, która pokazuje przykład:
źródło
both
go na funkcję i będzie on wywoływany / ponownie oceniany podczas procesu analizy kątowej. Zobacz to skrzypce na przykład. Również jeśli powiążesz z właściwością obiektu, możesz użyć go bezpośrednio w swoim widoku i zaktualizuje się on wraz ze zmianą danych, podobnie jak w tym przykładzie .getProperty()
funkcję do zakresu i użyć $ scope. $ Watch jak w tym przykładzie . Mam nadzieję, że te przykłady pomogą!.service
zamiast.factory
opisanego w dokumentach Angular. Dlaczego ta odpowiedź jest tak wysoko oceniana, skoro dokumentacja używa innej metody?Lubię ilustrować proste rzeczy prostymi przykładami :)
Oto bardzo prosty
Service
przykład:A tutaj jsbin
A oto bardzo prosty
Factory
przykład:A tutaj jsbin
Jeśli jest to zbyt proste, oto bardziej wyrafinowany przykład
Również zobaczyć odpowiedź tutaj najlepszych praktyk związanych komentarzach
źródło
var _dataObj = {};
gdy zwracasz bezpośrednie odniesienie do niego ..? To nie jest prywatne . W pierwszym przykładzie możesz to zrobić,this.dataObj = {};
aw drugimreturn { dataObj: {} };
jest to bezużyteczna deklaracja zmiennej IMHO.--- Wiem, że ta odpowiedź nie dotyczy tego pytania, ale chcę, aby osoby, które przeczytały to pytanie i chciały obsługiwać usługi takie jak fabryki, aby uniknąć problemów z zrobieniem tego ----
W tym celu musisz skorzystać z Usługi lub Fabryki.
Usługi są NAJLEPSZĄ PRAKTYKĄ w zakresie udostępniania danych między nie zagnieżdżonymi kontrolerami.
Bardzo dobrą adnotacją na ten temat na temat udostępniania danych jest sposób deklarowania obiektów. Miałem pecha, ponieważ wpadłem w pułapkę AngularJS, zanim o tym przeczytałem, i byłem bardzo sfrustrowany. Pozwól, że pomogę ci uniknąć tego problemu.
Czytam z „ng-book: Cała książka o AngularJS”, że modele ng AngularJS, które są tworzone w kontrolerach jako same dane, są NIEPRAWIDŁOWE!
Element zakresu $ powinien zostać utworzony w następujący sposób:
I nie tak:
Jest tak, ponieważ zaleca się (NAJLEPSZA PRAKTYKA), aby DOM (dokument HTML) zawierał wywołania jako
Jest to bardzo pomocne dla kontrolerów zagnieżdżonych, jeśli chcesz, aby kontroler podrzędny mógł zmienić obiekt z kontrolera nadrzędnego ....
Ale w twoim przypadku nie chcesz zagnieżdżonych zakresów, ale istnieje podobny aspekt pobierania obiektów z usług do kontrolerów.
Załóżmy, że masz swoją usługę „Fabryka”, aw przestrzeni powrotnej znajduje się obiekt A zawierający obiekt B zawierający obiekt C.
Jeśli ze swojego kontrolera chcesz dostać obiekt C do swojego zakresu, błędem jest powiedzieć:
To nie zadziała ... Zamiast tego użyj tylko jednej kropki.
Następnie w DOM można wywołać objectC z objectA. Jest to najlepsza praktyka związana z fabrykami, a co najważniejsze, pomoże uniknąć nieoczekiwanych i niemożliwych do złapania błędów.
źródło
Rozwiązanie bez tworzenia usługi przy użyciu $ rootScope:
Aby udostępnić właściwości między kontrolerami aplikacji, możesz użyć Angular $ rootScope. To kolejna opcja udostępniania danych, dzięki czemu ludzie o nich wiedzą.
Preferowanym sposobem udostępniania niektórych funkcji między kontrolerami są Usługi, do odczytu lub zmiany globalnej właściwości, której można użyć $ rootscope.
Używanie $ rootScope w szablonie (Dostęp do właściwości za pomocą $ root):
źródło
Powyższa próbka działała jak urok. Właśnie zrobiłem modyfikację na wypadek, gdy muszę zarządzać wieloma wartościami. Mam nadzieję, że to pomoże!
źródło
.factory
..service
Powinny być stosowane „jeśli zdefiniować jako usługi typu / klasy” jak za docs.angularjs.org/api/auto/service/$provide#serviceZwykle używam wartości, chętnie dyskutując, dlaczego to zły pomysł.
Następnie wprowadź wartość zgodnie z usługą.
Ustaw w ctrl1:
i dostęp z ctrl2:
źródło
Poniższy przykład pokazuje, jak przekazywać zmienne między kontrolerami rodzeństwa i podejmować działania w przypadku zmiany wartości.
Przykład zastosowania: na pasku bocznym znajduje się filtr, który zmienia zawartość innego widoku.
źródło
Chciałbym przyczynić się do tego pytania, wskazując, że zalecanym sposobem udostępniania danych między administratorami, a nawet dyrektywami, jest korzystanie z usług (fabryk), jak już wskazano, ale także chciałbym zapewnić praktyczny przykład tego, jak to zrobić.
Oto działający plunker: http://plnkr.co/edit/Q1VdKJP2tpvqqJL1LF6m?p=info
Po pierwsze, tworzyć swoją usługę , która będzie mieć swoje dane udostępnione :
Następnie po prostu wstrzyknij go do kontrolerów i pobierz współdzielone dane ze swojego zakresu:
Możesz to również zrobić dla swoich dyrektyw , działa to w ten sam sposób:
Mam nadzieję, że ta praktyczna i czysta odpowiedź może komuś pomóc.
źródło
Możesz to zrobić za pomocą usług lub fabryk. Są one zasadniczo takie same dla niektórych podstawowych różnic. To wyjaśnienie na thinkster.io uważam za najłatwiejsze do naśladowania. Prosty, konkretny i skuteczny.
źródło
Czy nie można również uczynić tej właściwości częścią nadrzędną dla zakresów?
Nie mówię, że to prawda, ale działa.
źródło
NOTE: These controllers are not nested inside each other.
. Gdyby to były zagnieżdżone kontrolery lub kontrolery, które współużytkowały tego samego rodzica, działałoby to, ale nie możemy się tego spodziewać.$parent
jeśli można tego uniknąć. Dobrze zaprojektowany komponent wielokrotnego użytku nie powinien wiedzieć o swoich rodzicach.Ach, miej trochę tych nowych rzeczy jako kolejną alternatywę. Jest to magazyn lokalny i działa tam, gdzie działa kąt. Nie ma za co. (Ale naprawdę, dziękuję facetowi)
https://github.com/gsklee/ngStorage
Określ swoje ustawienia domyślne:
Uzyskaj dostęp do wartości:
Zapisz wartości
Pamiętaj, aby wstrzyknąć ngStorage do swojej aplikacji i $ localStorage do kontrolera.
źródło
Można to zrobić na dwa sposoby
1) Skorzystaj z usługi get / set
2)
$scope.$emit('key', {data: value}); //to set the value
źródło
Drugie podejście:
HTML:
Aby uzyskać więcej informacji, zobacz plunker:
http://plnkr.co/edit/cKVsPcfs1A1Wwlud2jtO?p=preview
źródło
Ctrl2
(nasłuchujący) jest kontrolerem potomnymCtrl1
. Kontrolery rodzeństwa muszą się komunikować za pośrednictwem$rootScope
.Jeśli nie chcesz świadczyć usługi, możesz to zrobić w ten sposób.
źródło
Oprócz $ rootScope i usług, istnieje czyste i łatwe alternatywne rozwiązanie do rozszerzenia kąta w celu dodania współdzielonych danych:
w kontrolerach:
Te właściwości należą do „kątowego” obiektu, oddzielonego od zakresów i mogą być współużytkowane w zakresach i usługach.
Zaletą tego jest to, że nie musisz wstrzykiwać obiektu: są one dostępne w dowolnym miejscu natychmiast po zdeklasowaniu!
źródło
window
obiekcie ... Jeśli zamierzasz zanieczyścić kątowo, dlaczego po prostu nie zanieczyszczaj obiektu okna ...