stateparams sref angularjs angular-ui angular-ui-router

angularjs - sref - ui-router angular 6



Dos vistas en un ámbito de intercambio de estado de AngularUI Router (2)

Soy bastante nuevo en el enrutador AngularUI y me gustaría usarlo para el siguiente escenario:

El diseño común a todas las páginas incluye una barra de navegación superior que contiene un menú con botones a la derecha y una sección de contenido que llena el espacio a continuación. La página tiene varias páginas que asigno a los estados del enrutador de IU (página 1, página 2, ...). Cada página puede tener sus propios elementos de menú y su propio contenido. El menú debe compartir el alcance con el contenido, ya que interactúan (por ejemplo, el botón Guardar envía el formulario en el contenido, solo debe habilitarse si el formulario es válido).

El HTML se parece aproximadamente a esto:

<body> <nav class="..."> <h1>my site</h1> <div>MENU SHOULD GO HERE</div> </nav> <div class="row"> <div class="column ..."> CONTENT SHOULD GO HERE </div> </div> </body>

En este momento, estoy usando dos vistas paralelas y dos controladores para cada estado. Pero de esta manera, los dos ámbitos / controladores no pueden interactuar.

Entonces, ¿cómo lograrías eso?


$ scope no es el modelo, es una referencia a un modelo, se pega entre los datos y la vista. Si $ scopes en dos o más, los controladores necesitan compartir un modelo / estado / datos, usar una instancia de objeto singleton registrando un servicio angular. Ese único servicio / fábrica se puede inyectar en tantos controladores como desee, y luego todo puede funcionar con esa única fuente de verdad.

Aquí hay una demostración de 1 fábrica que vincula $ scopes en navbar & body con ui-router http://plnkr.co/edit/P2UudS?p=preview (solo pestaña izquierda)

ui-router (viewC es la barra de navegación):

$stateProvider .state(''left'', { url: "/", views: { "viewA": { controller: ''LeftTabACtrl'', template: ''Left Tab, index.viewA <br>'' + ''<input type="checkbox" ng-model="selected2.data" />'' + ''<pre>selected2.data: {{selected2.data}}</pre>'' }, {...}, "viewC": { controller: ''NavbarCtrl'', template: ''<span>Left Tab, index.viewC <div ui-view="viewC.list"></div>'' + ''<input type="checkbox" ng-model="selected.data" />'' + ''<pre>selected.data: {{selected.data}}</pre></span>'' } } })

Fábrica y controladores:

app.factory(''uiFieldState'', function () { return {uiObject: {data: null}} }); app.controller(''NavbarCtrl'', [''$scope'', ''uiFieldState'', ''$stateParams'', ''$state'', function($scope, uiFieldState, $stateParams, $state) { $scope.selected = uiFieldState.uiObject; } ]); app.controller(''LeftTabACtrl'', [''$scope'', ''uiFieldState'', ''$stateParams'', ''$state'', function($scope, uiFieldState, $stateParams, $state) { $scope.selected2 = uiFieldState.uiObject; } ]);

Como puede ver, el objeto de fábrica {uiObject: {data: null}} se inyecta en el controlador con uiFieldState y luego simplemente $scope.selected = uiFieldState.uiObject; para conectar la fábrica al alcance ng-model="selected.data" .`


Deberías usar:

$on and $emit

El controlador de emisión, que envía los datos.

angular.module(''MyApp'').controller(''MyController'', [''$scope'', ''$rootScope'', function ($scope, $rootScope){ $rootScope.$emit(''SomeEvent'', data); }]);

Un ejemplo de cómo implementar $ rootScope de una manera segura para que destruya y arregle cosas después de su uso:

angular .module(''MyApp'') .config([''$provide'', function($provide){ $provide.decorator(''$rootScope'', [''$delegate'', function($delegate){ Object.defineProperty($delegate.constructor.prototype, ''$onRootScope'', { value: function(name, listener){ var unsubscribe = $delegate.$on(name, listener); this.$on(''$destroy'', unsubscribe); }, enumerable: false }); return $delegate; }]); }]);

Y el controlador con los datos que deben ser tratados.

angular.module(''MyApp'') .controller(''MySecondController'', [''$scope'', function MyController($scope) { $scope.$onRootScope(''SomeEvent'', function(event, data){ console.log(data); }); } ]);

Podría pasar $ rootScope en lugar de usar el método $ scopes $ onRootScope que definimos en la configuración. Sin embargo, esta no es una forma recomendada de usar $ emit y $ onRootScope.

En lugar de usar $ emit, siempre puede usar $ broadcast. Sin embargo, esto le daría grandes problemas de rendimiento a medida que su aplicación crezca. Ya que burbujea los datos a través de todos los controladores.

Si sus controladores son padres e hijos, no tienen que usar el $ rootScope.

Aquí está un ejemplo de la diferencia entre $ jsFiddle y $ broadcast: jsFiddle

Y su es realmente diferencias de rendimiento: