Comment puis-je partager des données $scope entre les états dans angularjs ui-router?
sans utiliser un service ou construire des watchers dans le contrôleur parent, comment pourrait-on donner aux enfants l'accès aux États du contrôleur principal $scope
.
.state("main", {
controller:'mainController',
url:"/main",
templateUrl: "main_init.html"
})
.state("main.1", {
controller:'mainController',
parent: 'main',
url:"/1",
templateUrl: 'form_1.html'
})
.state("main.2", {
controller:'mainController',
parent: 'main',
url: "/2",
templateUrl: 'form_2.html'
})
Je ne suis pas capable d'accéder au champ principal du contrôleur dans l'état de l'enfant--ou plutôt je reçois un autre exemple de ce champ--pas ce que je veux. J'ai l'impression de rater quelque chose de simple. Il y a une option de configuration de données partagées dans l'objet state mais je ne suis pas sûr que cela devrait être utilisé pour quelque chose pareil.
5 réponses
I crée plongeur de travail , montrant comment utiliser $scope
et UI-routeur.
la définition de l'état est inchangée:
$stateProvider
// States
.state("main", {
controller:'mainController',
url:"/main",
templateUrl: "main_init.html"
})
.state("main.1", {
controller:'mainController',
parent: 'main',
url:"/1",
templateUrl: 'form_1.html'
})
.state("main.2", {
controller:'mainController',
parent: 'main',
url: "/2",
templateUrl: 'form_2.html'
})
mais chaque État peut avoir un contrôleur différent. Pourquoi? parce que chaque view
de chaque état obtient new
instance de défini controller
. Donc pendant que nous avons mainController
comme celui ci-dessous, nous pouvons être sûrs, que si nous naviguons à l'état 'main.2'
il sera instancié deux fois.
controller('mainController', function ($scope) {
$scope.Model = $scope.Model || {Name : "xxx"};
})
mais ce que nous pouvons voir ici , c'est que nous vérifions si $scope.Model
existe déjà... et si ce n'est pas (État Parent) nous l'instancions avec nouvelle intance {Name : "xxx"}
.
Eh bien, ce que je dis est: seul l'état parent sera dans le $scope.Model
. Tout d'autres recevront déjà rempli. Comment? Voici la réponse:
portée Héritage par vue hiérarchie seulement
gardez à l'esprit que les propriétés de scope héritent seulement en bas de la chaîne d'état si les vues de vos états sont emboîtées. Héritage des propriétés de scope n'a rien à voir avec la nidification de vos états et tout à voir avec la nidification de vos vues (gabarits).
il est tout à fait possible que vous ayez des États imbriqués dont les gabarits peuplent les vues-ui à divers endroits non imbriqués dans votre site. Dans ce scénario, vous ne pouvez pas vous attendre à accéder aux variables de portée des opinions de l'état parent dans les opinions des États enfants.
ainsi, comme indiqué dans la documentation. Comme les opinions de nos enfants sont imbriquées dans celles des parents, la portée est héréditaire.
La Compréhension Des Étendues
Dans AngularJS, un enfant normalement fait hérite de son parent.
...ayant un"."dans vos modèles s'assurera que l'héritage prototypique est en jeu.
// So, use
<input type="text" ng-model="someObj.prop1">
// rather than
<input type="text" ng-model="prop1">.
Et c'est tout. Nous obtenons l'héritage de UI-Router
vues et lunettes angulaires, et parce que nous avons utilisé intelligemment un type de référence ( Model
), c. - à-d. ont '.'
point dans ng-model
définition-nous pouvons partager des données maintenant
NOTE: "dans le ng-model="Model.PropertyName
signifie simplement, qu'il ya un reference
objet Model {}
avec une certaine propriété: PropertyName
cochez la case exemple pratique ici
vous pouvez obtenir l'ensemble de la portée par $rootScope . Si vous n'avez besoin que d'une partie de la portée, ui-router a une fonction custom data .
Voici comment faire un formulaire en plusieurs étapes. J'ai eu besoin des routes pour contenir des informations sur leurs étapes dans le flux.
tout D'abord, j'ai quelques routes avec L'UI-router:
// Sign UP routes
.state('sign-up', {
abstract: true,
url: '/sign-up',
controller: 'SignupController',
templateUrl: 'sign-up/index.html',
})
.state('sign-up.start', {
url: '-start',
templateUrl: 'sign-up/sign-up.start.html',
data: { step: 0, title: 'Welcome to Mars!', },
})
.state('sign-up.expertise', {
url: '-expertise',
templateUrl: 'sign-up/sign-up.expertise.html',
data: { step: 1, title: 'Your Expertise'},
})
Avis:
- le
data
élément dans chaque itinéraire. - l'état
abstract
aSignupController
. C'est le seul contrôleur de ce formulaire à étapes multiples. Leabstract
n'est pas nécessaire, mais il a du sens pour ce cas d'utilisation.
SignupController.js
angular.module('app').controller('SignupController', function($scope, $state) {
$scope.state = $state;
});
ici nous obtenons l'ui-router $state
et le mettons sur $scope
voici le modèle principal 'inscription/index.html',:
<h2>{{state.current.data.title}}</h2>
<div>This is a multi-step-progress control {{state.current.data.step}}</div>
<form id="signUpForm" name="signUpForm" novalidate>
<div ui-view></div>
</form>
les modèles pour enfants peuvent être ce qu'ils veulent.
l'idée est que vous utilisez la portée dans le parent - > héritage de l'enfant:
.state("main", {
controller:'mainController',
abstract: true,
url:"/main",
templateUrl: "main_init.html"
})
.state("main.1", {
controller:'mainController1',
parent: 'main',
url:"/1",
templateUrl: 'form_1.html'
})
.state("main.2", {
controller:'mainController2',
parent: 'main',
url: "/2",
templateUrl: 'form_2.html'
})
que l'utilisation est simple, vous avez 3 contrôleurs, un est partagé (mainController) et chaque vue a sa propre.
si vous utilisez des vues imbriquées, n'écrivez aucun autre contrôleur. De cette façon, ils partageront les mêmes données du contrôleur.
.state("main", {
url: "/main",
templateUrl: "templates/Ders",
controller: "DersController as DersC"
}).state("main.child1", {
url: "/child1",
templateUrl: "templates/Ders/child1"
}).state("main.child2", {
url: "/child2",
templateUrl: "templates/Ders/child2"
})
N'est-ce pas la solution la plus simple pour regrouper des variables partagées dans un service auquel vous pouvez accéder dans chaque contrôleur ? ...