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.

70
demandé sur Kris Roofe 2014-12-30 00:54:39

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

106
répondu Radim Köhler 2016-11-07 15:37:30

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 a SignupController . C'est le seul contrôleur de ce formulaire à étapes multiples. Le abstract 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.

14
répondu Michael Cole 2015-04-06 09:15:11

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.

8
répondu Ben Diamant 2014-12-29 21:59:42

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"
        })
6
répondu Bahtiyar Özdere 2015-09-29 19:23:27

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 ? ...

1
répondu hugsbrugs 2015-04-20 10:12:59