Tengo dos controladores angulares:
function Ctrl1($scope) {
$scope.prop1 = "First";
}
function Ctrl2($scope) {
$scope.prop2 = "Second";
$scope.both = Ctrl1.prop1 + $scope.prop2; //This is what I would like to do ideally
}
No puedo usar Ctrl1
adentro Ctrl2
porque no está definido. Sin embargo, si trato de pasarlo así ...
function Ctrl2($scope, Ctrl1) {
$scope.prop2 = "Second";
$scope.both = Ctrl1.prop1 + $scope.prop2; //This is what I would like to do ideally
}
Me sale un error ¿Alguien sabe como hacer esto?
Haciendo
Ctrl2.prototype = new Ctrl1();
También falla
NOTA: Estos controladores no están anidados uno dentro del otro.
javascript
angularjs
angularjs-controller
dopatraman
fuente
fuente
Respuestas:
Una forma de compartir variables entre varios controladores es crear un servicio e inyectarlo en cualquier controlador donde desee usarlo.
Ejemplo de servicio simple:
Usando el servicio en un controlador:
Esto se describe muy bien en este blog (Lección 2 y más en particular).
Descubrí que si desea enlazar estas propiedades a través de múltiples controladores, funciona mejor si se une a la propiedad de un objeto en lugar de un tipo primitivo (booleano, cadena, número) para retener la referencia enlazada.
Ejemplo: en
var property = { Property1: 'First' };
lugar devar property = 'First';
.ACTUALIZACIÓN: Para (con suerte) aclarar las cosas aquí, hay un violín que muestra un ejemplo de:
fuente
both
para que sea una función y se llamará / reevaluará durante el proceso de resumen angular. Vea este violín para ver un ejemplo. Además, si se vincula a la propiedad de un objeto, puede usarla directamente en su vista y se actualizará a medida que los datos cambien de manera similar a este ejemplo .getProperty()
función al ámbito y usar $ scope. $ Watch como en este ejemplo . Espero que estos ejemplos ayuden!.service
lugar de.factory
como se describe en los documentos angulares. ¿Por qué esta respuesta se vota tan alto cuando la documentación utiliza un método diferente?Me gusta ilustrar cosas simples con ejemplos simples :)
Aquí hay un
Service
ejemplo muy simple :Y aqui el jsbin
Y aquí hay un
Factory
ejemplo muy simple :Y aqui el jsbin
Si eso es demasiado simple, aquí hay un ejemplo más sofisticado
Consulte también la respuesta aquí para ver los comentarios relacionados con las mejores prácticas.
fuente
var _dataObj = {};
cuando devuelve una referencia directa a él ...? Eso no es privado . En el primer ejemplo que puede hacerthis.dataObj = {};
y en el segundoreturn { dataObj: {} };
es una declaración de variable inútil en mi humilde opinión.--- Sé que esta respuesta no es para esta pregunta, pero quiero personas que lean esta pregunta y quieran manejar Servicios como Fábricas para evitar problemas al hacer esto ----
Para ello, deberá utilizar un Servicio o una Fábrica.
Los servicios son la MEJOR PRÁCTICA para compartir datos entre controladores no anidados.
Una muy buena anotación sobre este tema sobre el intercambio de datos es cómo declarar objetos. Tuve mala suerte porque caí en una trampa AngularJS antes de leer sobre eso, y estaba muy frustrado. Déjame ayudarte a evitar este problema.
Leí del "ng-book: El libro completo sobre AngularJS" que los modelos ng de AngularJS que se crean en controladores como datos desnudos ¡ESTÁN INCORRECTOS!
Se debe crear un elemento $ scope así:
Y no así:
Esto se debe a que se recomienda (MEJOR PRÁCTICA) que el DOM (documento html) contenga las llamadas como
Esto es muy útil para los controladores anidados si desea que su controlador secundario pueda cambiar un objeto desde el controlador principal ...
Pero en su caso no desea ámbitos anidados, pero hay un aspecto similar para obtener objetos de los servicios a los controladores.
Digamos que tiene su servicio 'Factory' y en el espacio de retorno hay un objeto A que contiene un objeto B que contiene un objeto C.
Si desde su controlador desea OBTENER el objectC en su alcance, es un error decir:
Eso no funcionará ... En su lugar, use solo un punto.
Luego, en el DOM puede llamar a objectC desde objectA. Esta es una práctica recomendada relacionada con las fábricas y, lo más importante, ayudará a evitar errores inesperados y no detectables.
fuente
Solución sin crear Servicio, usando $ rootScope:
Para compartir propiedades entre los Controladores de aplicaciones, puede usar Angular $ rootScope. Esta es otra opción para compartir datos, para que la gente lo sepa.
La forma preferida de compartir algunas funciones entre los Controladores es Servicios, para leer o cambiar una propiedad global puede usar $ rootscope.
Usando $ rootScope en una plantilla (Propiedades de acceso con $ root):
fuente
La muestra anterior funcionó a las mil maravillas. Acabo de hacer una modificación en caso de que necesite administrar varios valores. ¡Espero que esto ayude!
fuente
.factory
. A.service
debe usarse "si define su servicio como un tipo / clase" según docs.angularjs.org/api/auto/service/$provide#serviceTiendo a usar valores, me alegra que alguien discuta por qué es una mala idea.
Luego inyecte el valor según un servicio.
Establecer en ctrl1:
y acceso desde ctrl2:
fuente
El siguiente ejemplo muestra cómo pasar variables entre controladores hermanos y realizar una acción cuando el valor cambia.
Ejemplo de caso de uso: tiene un filtro en una barra lateral que cambia el contenido de otra vista.
fuente
Me gustaría contribuir a esta pregunta señalando que la forma recomendada de compartir datos entre los controladores, e incluso las directivas, es mediante el uso de servicios (fábricas) como ya se ha señalado, pero también me gustaría proporcionar un Ejemplo práctico de trabajo de cómo hacerlo.
Aquí está el plunker de trabajo: http://plnkr.co/edit/Q1VdKJP2tpvqqJL1LF6m?p=info
Primero, cree su servicio , que tendrá sus datos compartidos :
Luego, simplemente inyecte en sus controladores y tome los datos compartidos en su alcance:
También puede hacerlo para sus directivas , funciona de la misma manera:
Espero que esta respuesta práctica y limpia pueda ser útil para alguien.
fuente
Podrías hacerlo con servicios o fábricas. Son esencialmente iguales, aparte de algunas diferencias centrales. Encontré esta explicación en thinkster.io como la más fácil de seguir. Simple, directo y efectivo.
fuente
¿No podría también hacer que la propiedad sea parte de los ámbitos primarios?
No digo que sea correcto, pero funciona.
fuente
NOTE: These controllers are not nested inside each other.
. Si estos fueran controladores anidados o controladores que compartieran el mismo padre, esto funcionaría, pero no podemos esperar eso.$parent
si eso se puede evitar. Un componente reutilizable bien diseñado no debe conocer a sus padres.Ah, tenga un poco de estas cosas nuevas como otra alternativa. Es almacenamiento local y funciona donde funciona angular. De nada. (Pero realmente, gracias al chico)
https://github.com/gsklee/ngStorage
Defina sus valores predeterminados:
Acceda a los valores:
Almacenar los valores
Recuerde inyectar ngStorage en su aplicación y $ localStorage en su controlador.
fuente
Hay dos maneras de hacer esto
1) Use el servicio get / set
2)
$scope.$emit('key', {data: value}); //to set the value
fuente
Segundo enfoque
HTML:
Para más detalles ver plunker:
http://plnkr.co/edit/cKVsPcfs1A1Wwlud2jtO?p=preview
fuente
Ctrl2
(el oyente) es un controlador secundario deCtrl1
. Los controladores hermanos deben comunicarse a través de$rootScope
.Si no desea hacer el servicio, puede hacerlo así.
fuente
Además de $ rootScope y los servicios, hay una solución alternativa limpia y fácil de extender angular para agregar los datos compartidos:
en los controladores:
Estas propiedades pertenecen al objeto 'angular', separado de los ámbitos, y se pueden compartir en ámbitos y servicios.
Uno de los beneficios es que no tiene que inyectar el objeto: ¡son accesibles desde cualquier lugar inmediatamente después de su definición!
fuente
window
objeto ... Si vas a contaminar angularmente, ¿por qué no simplemente seguir contaminando el objeto de la ventana ...