Pregunta ¿Cómo comparto $ scope data entre estados en angularjs ui-router?


Sin usar un servicio o construir vigilantes en el controlador principal, ¿cómo le daría uno a los estados acceso al controlador 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'
      })  

No puedo acceder al ámbito mainController en estado hijo, o mejor dicho, estoy obteniendo otra instancia de ese ámbito, no es lo que quiero. Siento que me estoy perdiendo algo simple. Hay una opción de configuración de datos compartida en el objeto de estado, pero no estoy seguro de si esto debería usarse para algo como esto.


70
2017-12-29 21:54


origen


Respuestas:


yo creado plunker de trabajo, mostrando cómo usar $scope y UI-Router.

La definición de estado no se modifica:

$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'
  })  

Pero cada estado puede tener un controlador diferente. ¿Por qué? porque cada view de cada estado se pone new  ejemplo de definido controller. Entonces, mientras tenemos mainController como el de abajo, podemos estar seguros de que si navegamos hasta el estado 'main.2' será instanciado dos veces.

controller('mainController', function ($scope) {
  $scope.Model = $scope.Model || {Name : "xxx"};
})

Pero lo que podemos ver aquí, es que comprobamos si $scope.Model ya existe ... y si no (Estado principal) lo instanciamos con nueva intancia  {Name : "xxx"}.

Bueno, lo que estoy diciendo es: solo el estado padre iniciará el $scope.Model. Todos los demás obtendrán eso ya lleno. ¿Cómo? Bueno, aquí está la respuesta:

Herencia de alcance solo por jerarquía de vistas

Tenga en cuenta que las propiedades del alcance solo heredan en la cadena de estado si las vistas de sus estados están anidadas. La herencia de las propiedades del alcance no tiene nada que ver con la anidación de sus estados y todo lo relacionado con la anidación de sus vistas (plantillas).

Es muy posible que haya anidado estados cuyas plantillas llenan vistas de ui en varias ubicaciones no anidadas dentro de su sitio. En este escenario, no puede esperar acceder a las variables de ámbito de las vistas de estado primario dentro de las vistas de los estados secundarios.

Entonces, como se indica en la documentación. Debido a que nuestras vistas secundarias están anidadas en la vista principal, el alcance se hereda.

Entender los ámbitos

En AngularJS, un ámbito hijo normalmente hereda prototípicamente de su ámbito principal.
   ...

Teniendo un '.' en sus modelos se asegurará de que la herencia prototípica esté en juego.

// So, use
<input type="text" ng-model="someObj.prop1"> 
// rather than
<input type="text" ng-model="prop1">.

Y eso es. Obtenemos herencia de UI-Router vistas y ámbitos angulares, y porque usamos inteligentemente un tipo de referencia (Model), es decir, tienen '.' punto en ng-model definición - podemos compartir datos ahora

NOTA: tener punto '.' en el ng-model="Model.PropertyName simplemente significa que hay un reference objeto Model {} con alguna propiedad: PropertyName

Comprobar el ejemplo de trabajo aquí


104
2017-12-30 05:00



Puedes obtener todo el alcance a través de $ rootScope. Si necesita solo una parte del alcance, ui-router tiene una datos personalizados característica.

A continuación, le mostramos cómo hacer una forma de pasos múltiples. Necesitaba las rutas para contener información sobre sus pasos en el flujo.

Primero, tengo algunas rutas con UI-enrutador:

  // 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'},
  })

Darse cuenta:

  • el dataelemento en cada ruta.
  • los abstract estado tiene SignupController. Ese es el único controlador para esta forma de varios pasos. los abstract no es obligatorio, pero tiene sentido para este caso de uso.

SignupController.js

angular.module('app').controller('SignupController', function($scope, $state) {
  $scope.state = $state;
});

Aquí obtenemos el enrutador ui $state y póngalo $scope

Aquí está la plantilla principal 'sign-up / 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>

Las plantillas secundarias pueden ser lo que quieran.


14
2018-04-06 09:15



La idea es usar el alcance en herencia padre-> hijo:

 .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 el uso es simple, tiene 3 controladores, uno es compartido (mainController) y cada vista tiene su propio.


8
2017-12-29 21:59



Si está utilizando vistas anidadas simplemente no escriba ningún otro controlador. De esta forma, compartirán los mismos datos del controlador.

.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
2017-09-29 19:23



¿No es la solución más simple para agrupar variables compartidas en un servicio al que puede acceder en cada controlador? ...


1
2018-04-20 10:12