Próbuję udostępnić dane między administratorami. Przypadek użycia jest formularzem wieloetapowym, dane wprowadzone na jednym wejściu są później wykorzystywane w wielu lokalizacjach wyświetlania poza pierwotnym sterownikiem. Kod poniżej oraz w jsfiddle tutaj .
HTML
<div ng-controller="FirstCtrl">
<input type="text" ng-model="FirstName"><!-- Input entered here -->
<br>Input is : <strong>{{FirstName}}</strong><!-- Successfully updates here -->
</div>
<hr>
<div ng-controller="SecondCtrl">
Input should also be here: {{FirstName}}<!-- How do I automatically updated it here? -->
</div>
JS
// declare the app with no dependencies
var myApp = angular.module('myApp', []);
// make a factory to share data between controllers
myApp.factory('Data', function(){
// I know this doesn't work, but what will?
var FirstName = '';
return FirstName;
});
// Step 1 Controller
myApp.controller('FirstCtrl', function( $scope, Data ){
});
// Step 2 Controller
myApp.controller('SecondCtrl', function( $scope, Data ){
$scope.FirstName = Data.FirstName;
});
Każda pomoc jest mile widziana.
javascript
angularjs
johnkeese
źródło
źródło
Odpowiedzi:
Prostym rozwiązaniem jest zwrócenie obiektu do fabryki i umożliwienie kontrolerom pracy w odniesieniu do tego samego obiektu:
JS:
HTML:
Demo: http://jsfiddle.net/HEdJF/
Gdy aplikacje stają się większe, bardziej złożone i trudniejsze do przetestowania, możesz nie chcieć w ten sposób eksponować całego obiektu z fabryki, ale zamiast tego dać ograniczony dostęp, na przykład za pośrednictwem programów pobierających i ustawiających:
Przy takim podejściu do kontrolerów korzystających z oprogramowania należy aktualizowanie fabryki o nowe wartości i sprawdzanie zmian w celu ich uzyskania:
HTML:
Demo: http://jsfiddle.net/27mk1n1o/
źródło
return { FirstName: '' };
lub zwracający obiekt zawierający metody, które wchodzą w interakcje z obiektem, czy nie byłoby wskazane zwracanie instancji klasy (function
), aby podczas używania obiektu miał on określony typ i był nie tylko obiekt{}" ?newValue !== oldValue
sprawdzania, ponieważ Angular nie wykonuje tej funkcji, jeśli oldValue i newValue są takie same. Jedynym wyjątkiem jest sytuacja, gdy zależy Ci na wartości początkowej. Patrz: docs.quarejs.org/api/ng/type/$rootScope.Scope#$watchWolę nie używać
$watch
. Zamiast przypisywać całą usługę do zakresu kontrolera, możesz przypisać tylko dane.JS:
HTML:
Alternatywnie możesz zaktualizować dane usługi metodą bezpośrednią.
JS:
źródło
Istnieje wiele sposobów udostępniania danych między kontrolerami
Objaśnienie każdej metody:
Nie zamierzam wyjaśniać, ponieważ ktoś już to wyjaśnił
za pomocą
$state.go
$stateparam
działa w podobny sposób$state.go
, przekazujesz go jako obiekt z kontrolera nadawcy i zbierasz w kontrolerze odbiornika za pomocą stateparamza pomocą
$rootscope
(a) wysyłanie danych od dziecka do nadrzędnego kontrolera
(b) wysyłanie danych od nadrzędnego do kontrolera podrzędnego
źródło
Stworzyłem fabrykę, która kontroluje współużytkowany zakres między wzorcem ścieżki trasy, abyś mógł utrzymywać udostępnione dane tylko wtedy, gdy użytkownicy nawigują tą samą ścieżką nadrzędną trasy.
Jeśli więc użytkownik przejdzie do innej ścieżki trasy, na przykład „/ Wsparcie”, udostępnione dane dla ścieżki „/ Klient” zostaną automatycznie zniszczone. Ale jeśli zamiast tego użytkownik przejdzie do ścieżek „podrzędnych”, takich jak „/ Customer / 1” lub „/ Customer / list”, zakres nie zostanie zniszczony.
Możesz zobaczyć próbkę tutaj: http://plnkr.co/edit/OL8of9
źródło
$rootScope.$on('$stateChangeSuccess', function(event, toState, toParams, fromState, fromParams){ ... })
jeśli masz ui.routerIstnieje wiele sposobów udostępniania danych między kontrolerami
Jak wiemy
$rootscope
nie jest to preferowany sposób przesyłania danych lub komunikacji, ponieważ jest to globalny zakres, który jest dostępny dla całej aplikacjiW zakresie udostępniania danych między kontrolerami Angular Js najlepsze są np. Usługi Angular.
.factory
,.service
W celach informacyjnych
W przypadku transferu danych z rodzica na dziecko można kontrolera dostępu do danych bezpośrednio dominującym w kontrolerze dzieci poprzez
$scope
Jeśli używasz
ui-router
następnie można użyć$stateParmas
do przekazywania parametrów URL jakid
,name
,key
itp$broadcast
jest również dobrym sposobem na przesyłanie danych między kontrolerami z nadrzędnego na podrzędny i$emit
transfer danych z podrzędnych do nadrzędnychHTML
JS
Zapoznaj się z podanym linkiem, aby dowiedzieć się więcej
$broadcast
źródło
Najprostsze rozwiązanie:
Korzystałem z usługi AngularJS .
Krok 1: Utworzyłem usługę AngularJS o nazwie SharedDataService.
Krok 2: Utwórz dwa kontrolery i użyj wyżej utworzonej usługi.
Krok 3: Po prostu użyj utworzonych kontrolerów w widoku.
Aby zobaczyć działające rozwiązanie tego problemu, kliknij poniższy link
https://codepen.io/wins/pen/bmoYLr
plik .html:
źródło
FirstCtrl
jest rodzicem i dostaje obietnicę, którejSecondCtrl
(dziecko) będzie potrzebować? Nie chcę wykonywać dwóch połączeń API. Dzięki.Istnieje inny sposób bez użycia $ watch, używając angular.copy:
źródło
Można to zrobić na wiele sposobów.
Wydarzenia - już dobrze wyjaśnione.
router interfejsu użytkownika - wyjaśniono powyżej.
*
*
źródło
Nie wiem, gdzie wybrałem ten wzorzec, ale działa to wspaniale w przypadku udostępniania danych między kontrolerami i zmniejszenia $ rootScope i $ scope. Przypomina replikację danych, w której są wydawcy i subskrybenci. Mam nadzieję, że to pomoże.
Obsługa:
Administrator, który pobiera nowe dane, czyli Wydawca, zrobiłby coś takiego.
Administrator, który również korzysta z tych nowych danych, zwany subskrybentem, zrobiłby coś takiego ...
Będzie to działać w każdym scenariuszu. Więc kiedy główny kontroler zostanie zainicjowany i pobierze dane, wywołałby metodę changeData, która następnie rozesłałaby to do wszystkich subskrybentów tych danych. Zmniejsza to sprzężenie naszych sterowników ze sobą.
źródło
sharedDataEventHub.changeData(newData)
sharedDataEventHub.changeData(newData)
dowolnego elementu potomnego lub kontrolera zależnego od tych danych, który miałby gdzieś w ciele kontrolera:sharedDataEventHub.onChangeData($scope, function(obj) { vm.myObject = obj.data; });
Jeśli użyjesz interfejsu użytkownika -Router może zostać wstrzyknięty z konfiguracji stanu.Po prostu zrób to prosto (testowane w wersji 1.3.15):
źródło
dummy
jest globalny dla obu kontrolerów, a nie współdzielony w bardziej modułowy sposób poprzez dziedziczenie z $ scope lub controllerAs lub za pomocą usługi.