Estoy tratando de compartir datos entre los controladores. El caso de uso es un formulario de varios pasos, los datos ingresados en una entrada se usan más tarde en múltiples ubicaciones de visualización fuera del controlador original. Código a continuación y en jsfiddle aquí .
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;
});
Cualquier ayuda es muy apreciada.
javascript
angularjs
johnkeese
fuente
fuente
Respuestas:
Una solución simple es que su fábrica devuelva un objeto y permita que sus controladores trabajen con una referencia al mismo objeto:
JS:
HTML:
Demostración: http://jsfiddle.net/HEdJF/
Cuando las aplicaciones se hacen más grandes, más complejas y más difíciles de probar, es posible que no desee exponer todo el objeto de la fábrica de esta manera, sino que, en cambio, otorgue acceso limitado, por ejemplo, a través de getters y setters:
Con este enfoque, corresponde a los controladores consumidores actualizar la fábrica con nuevos valores y observar los cambios para obtenerlos:
HTML:
Demostración: http://jsfiddle.net/27mk1n1o/
fuente
return { FirstName: '' };
o devolver un objeto que contiene métodos que interactúan con un objeto, ¿no sería preferible devolver una instancia de una clase (function
) para que cuando use su objeto, tenga un tipo específico y no solo sea un objeto{}" ?newValue !== oldValue
verificación porque Angular no ejecuta la función si oldValue y newValue son iguales. La única excepción a esto es si le importa el valor inicial. Ver: docs.angularjs.org/api/ng/type/$rootScope.Scope#$watchPrefiero no usar
$watch
para esto. En lugar de asignar todo el servicio al alcance de un controlador, puede asignar solo los datos.JS:
HTML:
Alternativamente, puede actualizar los datos del servicio con un método directo.
JS:
fuente
Hay muchas maneras de compartir los datos entre los controladores.
Explicación de cada método:
No voy a explicar ya que alguien ya lo explicó
utilizando
$state.go
$stateparam
funciona de manera similar$state.go
, lo pasa como objeto desde el controlador del remitente y lo recopila en el controlador del receptor utilizando stateparamutilizando
$rootscope
(a) enviar datos del controlador hijo al padre
(b) enviar datos del controlador principal al controlador secundario
fuente
Creé una fábrica que controla el alcance compartido entre el patrón de ruta de ruta, para que pueda mantener los datos compartidos justo cuando los usuarios navegan en la misma ruta principal de ruta.
Entonces, si el usuario va a otra ruta de ruta, por ejemplo '/ Soporte', los datos compartidos para la ruta '/ Cliente' se destruirán automáticamente. Pero, si en lugar de esto, el usuario va a rutas 'secundarias', como '/ Cliente / 1' o '/ Cliente / lista', el alcance no se destruirá.
Puede ver una muestra aquí: http://plnkr.co/edit/OL8of9
fuente
$rootScope.$on('$stateChangeSuccess', function(event, toState, toParams, fromState, fromParams){ ... })
si tiene ui.routerExisten múltiples formas de compartir datos entre controladores
Como sabemos,
$rootscope
no es una forma preferible para la transferencia de datos o la comunicación porque es un alcance global que está disponible para toda la aplicaciónPara compartir datos entre controladores Angular Js, los servicios angulares son las mejores prácticas, por ejemplo.
.factory
,.service
Para referencia
En caso de transferencia de datos de padre a hijo controlador se puede acceder directamente a los datos de los padres en el controlador infantil a través
$scope
Si está utilizando
ui-router
entonces se puede utilizar$stateParmas
para pasar parámetros URL comoid
,name
,key
, etc.$broadcast
También es una buena manera de transferir datos entre controladores de padres a hijos y$emit
de transferir datos de controladores hijos a padresHTML
JS
Consulte el enlace dado para saber más sobre
$broadcast
fuente
La solución más simple:
He usado un servicio AngularJS .
Paso 1: he creado un servicio AngularJS llamado SharedDataService.
Paso 2: Cree dos controladores y use el servicio creado anteriormente.
Paso 3: simplemente use los controladores creados en la vista.
Para ver una solución funcional a este problema, presione el siguiente enlace
https://codepen.io/wins/pen/bmoYLr
archivo .html:
fuente
FirstCtrl
es padre y recibe una promesa queSecondCtrl
(niño) también necesitará? No quiero hacer dos llamadas api. Gracias.Hay otra forma sin usar $ watch, usando angular.copy:
fuente
Hay varias formas de hacer esto.
Eventos - ya explicados bien.
enrutador ui - explicado anteriormente.
* *
* *
fuente
No estoy seguro de dónde tomé este patrón, pero para compartir datos entre controladores y reducir $ rootScope y $ scope, esto funciona muy bien. Es una reminiscencia de una replicación de datos donde tienes editores y suscriptores. Espero eso ayude.
El servicio:
El controlador que está obteniendo los nuevos datos, que es el editor, haría algo como esto ...
El controlador que también está utilizando estos nuevos datos, que se llama suscriptor, haría algo como esto ...
Esto funcionará para cualquier escenario. Entonces, cuando el controlador primario se inicializa y obtiene datos, llamará al método changeData, que luego lo transmitirá a todos los suscriptores de esos datos. Esto reduce el acoplamiento de nuestros controladores entre sí.
fuente
sharedDataEventHub.changeData(newData)
sharedDataEventHub.changeData(newData)
cualquier elemento secundario o controlador que dependa de esos datos tendría en algún lugar de su cuerpo del controlador lo siguiente:sharedDataEventHub.onChangeData($scope, function(obj) { vm.myObject = obj.data; });
Si usó la IU -Router esto podría inyectarse desde la configuración de estado.Simplemente hazlo simple (probado con v1.3.15):
fuente
dummy
es global para ambos controladores en lugar de compartirse de forma más modular a través de la herencia con $ scope o controllerAs o mediante un servicio.