J'essaie de partager des données entre les contrôleurs. Le cas d'utilisation est un formulaire en plusieurs étapes, les données entrées dans une entrée sont ensuite utilisées dans plusieurs emplacements d'affichage en dehors du contrôleur d'origine. Code ci-dessous et dans jsfiddle ici .
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;
});
Toute aide est grandement appréciée.
javascript
angularjs
johnkeese
la source
la source
Réponses:
Une solution simple est que votre usine retourne un objet et que vos contrôleurs fonctionnent avec une référence au même objet:
JS:
HTML:
Démo: http://jsfiddle.net/HEdJF/
Lorsque les applications deviennent plus grandes, plus complexes et plus difficiles à tester, vous ne souhaiterez peut-être pas exposer l'objet entier de l'usine de cette façon, mais accordez plutôt un accès limité, par exemple via des getters et des setters:
Avec cette approche, il appartient aux contrôleurs consommateurs de mettre à jour l'usine avec de nouvelles valeurs et de surveiller les changements pour les obtenir:
HTML:
Démo: http://jsfiddle.net/27mk1n1o/
la source
return { FirstName: '' };
ou de renvoyer un objet contenant des méthodes qui interagissent avec un objet, ne serait-il pas préférable de renvoyer une instance d'une classe (function
) de sorte que lorsque vous utilisez votre objet, il ait un type spécifique et ce n'est pas seulement un objet{}" ?newValue !== oldValue
Attention , la fonction d'écoute n'a pas besoin d'être vérifiée car Angular n'exécute pas la fonction si oldValue et newValue sont identiques. La seule exception à cela est si vous vous souciez de la valeur initiale. Voir: docs.angularjs.org/api/ng/type/$rootScope.Scope#$watchJe préfère ne pas l'utiliser
$watch
pour cela. Au lieu d'affecter l'intégralité du service à l'étendue d'un contrôleur, vous pouvez affecter uniquement les données.JS:
HTML:
Vous pouvez également mettre à jour les données de service avec une méthode directe.
JS:
la source
Il existe de nombreuses façons de partager les données entre les contrôleurs
Explication de chaque méthode:
Je ne vais pas expliquer comme c'est déjà expliqué par quelqu'un
en utilisant
$state.go
$stateparam
fonctionne de la même manière que$state.go
, vous le transmettez en tant qu'objet du contrôleur émetteur et le récupérez dans le contrôleur récepteur à l'aide de stateparamen utilisant
$rootscope
(a) envoyer des données de l'enfant au contrôleur parent
(b) envoyer des données du parent au contrôleur enfant
la source
J'ai créé une fabrique qui contrôle la portée partagée entre le modèle du chemin de l'itinéraire, afin que vous puissiez conserver les données partagées juste lorsque les utilisateurs naviguent dans le même chemin parent de l'itinéraire.
Ainsi, si l'utilisateur accède à un autre chemin de l'itinéraire, par exemple «/ Support», les données partagées pour le chemin «/ Client» seront automatiquement détruites. Mais, si au lieu de cela, l'utilisateur va sur les chemins "enfants", comme "/ Client / 1" ou "/ Client / liste", la portée ne sera pas détruite.
Vous pouvez voir un exemple ici: http://plnkr.co/edit/OL8of9
la source
$rootScope.$on('$stateChangeSuccess', function(event, toState, toParams, fromState, fromParams){ ... })
si vous avez ui.routerIl existe plusieurs façons de partager des données entre les contrôleurs
Comme nous le savons, ce
$rootscope
n'est pas un moyen préférable pour le transfert de données ou la communication car c'est une portée mondiale qui est disponible pour toute l'applicationPour le partage de données entre les contrôleurs Angular Js, les services angulaires sont les meilleures pratiques, par exemple.
.factory
,.service
Pour référence
En cas de transfert de données du parent au contrôleur de l' enfant , vous pouvez données parent directement accès au contrôleur de l' enfant par le biais
$scope
Si vous utilisez ,
ui-router
vous pouvez ensuite utiliser$stateParmas
pour passer des paramètres d'URL commeid
,name
,key
, etc.$broadcast
est également un bon moyen de transférer des données entre les contrôleurs du parent vers l'enfant et$emit
de transférer les données de l'enfant vers les contrôleurs parentHTML
JS
Référez-vous au lien donné pour en savoir plus sur
$broadcast
la source
Solution la plus simple:
J'ai utilisé un service AngularJS .
Étape 1: J'ai créé un service AngularJS nommé SharedDataService.
Étape 2: créez deux contrôleurs et utilisez le service créé ci-dessus.
Étape 3: utilisez simplement les contrôleurs créés dans la vue.
Pour voir la solution de travail à ce problème, veuillez cliquer sur le lien ci-dessous
https://codepen.io/wins/pen/bmoYLr
Fichier .html:
la source
FirstCtrl
est parent et obtient une promesse dontSecondCtrl
(enfant) aura également besoin? Je ne veux pas passer deux appels API. Merci.Il y a une autre façon sans utiliser $ watch, en utilisant angular.copy:
la source
Il existe plusieurs façons de procéder.
Événements - déjà bien expliqué.
routeur ui - expliqué ci-dessus.
*
*
la source
Je ne sais pas où j'ai choisi ce modèle, mais pour le partage de données entre les contrôleurs et la réduction de $ rootScope et $ scope, cela fonctionne très bien. Cela rappelle une réplication de données où vous avez des éditeurs et des abonnés. J'espère que cela aide.
Le service:
Le contrôleur qui obtient les nouvelles données, c'est-à-dire l'éditeur ferait quelque chose comme ça.
Le contrôleur qui utilise également ces nouvelles données, appelé l'abonné, ferait quelque chose comme ça ...
Cela fonctionnera pour n'importe quel scénario. Ainsi, lorsque le contrôleur principal est initialisé et obtient des données, il appelle la méthode changeData qui la diffuse ensuite à tous les abonnés de ces données. Cela réduit le couplage de nos contrôleurs entre eux.
la source
sharedDataEventHub.changeData(newData)
sharedDataEventHub.changeData(newData)
alors le tout enfant ou contrôleur qui dépend de ces données aurait quelque part dans leur corps de contrôleur ce qui suit:sharedDataEventHub.onChangeData($scope, function(obj) { vm.myObject = obj.data; });
Si vous avez utilisé l'interface utilisateur -Router cela pourrait être injecté depuis la configuration de l'état.Faites-le simplement (testé avec la v1.3.15):
la source
dummy
est global pour les deux contrôleurs plutôt que partagé de manière plus modulaire via l'héritage avec $ scope ou controllerAs ou en utilisant un service.