not angularjs angularjs-scope

not - Herencia del controlador AngularJS



rootscope angularjs (6)

AngularJS tiene una herencia de controlador basada en DOM, como se menciona en los Documentos angulares.

<div ng-controller="BaseController"> <p>Base Controller Value: {{value}}</p> <button ng-click="updateValue()">Update In Base</button> <div ng-controller="DerivedController"> <p>Derived Controller Value: {{value}}</p> <button ng-click="updateValue()">Update In Derived</button> </div> </div>

La variable de alcance "valor" solo está presente en el BaseController. Basado en esto, al cambiar el valor en un método en BaseController o DerivedController, quiero que ambos valores se actualicen. Pero solo la variable de ámbito individual se actualiza.

Aquí hay un violín que demuestra el mismo ejemplo: http://jsfiddle.net/6df6S/1/

¿Cómo se pueden hacer los cambios en un nivel para propagar al hijo inmediato y al padre inmediato del alcance actual?

Podemos implementar esto usando

$ scope. $ watch

¿Hay alguna manera de hacer esto sin usarlo o cualquiera de esos observadores?

Editar 1:

Usando $ scope. $ Watch aquí es lo que quise decir

$scope.$watch("value", function () { $scope.$broadcast("childChangeListener"); //Downwards to all children scopes $scope.$emit("parentChangeListener"); //Upwards to all parent scopes });

Estaba buscando la manera de actualizar el valor en todos los ámbitos sin utilizar dicho mecanismo.


El enlace en su violín está directamente en una propiedad en el alcance. La herencia que necesita puede lograrse teniendo el enlace de datos en un objeto en el alcance.

http://jsfiddle.net/2Dtyq/

scope.shared = {} scope.shared.value = "Something"

En lugar de simplemente

scope.value= "Something"

¿Que esta pasando?
Mientras se construye DerivedController, el alcance que se pasa prototípicamente hereda del alcance de BaseController.
El objeto de alcance de DerivedController aún no tiene su propia propiedad llamada "valor". Por lo tanto, aún se une a la propiedad que obtuvo del alcance de los padres.
Ahora, si hace clic en el botón Actualizar en la base , se reflejará en ambas vinculaciones. En el momento en que hace clic en Actualizar en el botón Derivado , se crea una nueva propiedad llamada "valor" en el alcance de DerviedController. Por lo tanto, el enlace a la propiedad de valor del padre está roto. Si se hacen más clics en Actualizar en base, no se actualiza el segundo enlace de datos.
Ponerlo en un objeto separado evita que se cree una propiedad nueva, por lo que la herencia se mantiene.


No puede referirse directamente al valor de cadena en el controlador secundario. Debido a la herencia prototípica que establece el value propiedad en el ámbito hijo (que se crea cuando usa un controlador secundario) crea esa propiedad en el ámbito secundario en lugar de actualizar la propiedad del ámbito principal.

Su alcance no es el modelo y, por lo tanto, debemos evitar contaminar la variable $scope con muchas propiedades. Cree un objeto modelo y cree sub propiedades en él. Este objeto se puede pasar a lo largo del controlador / scope del niño.

Modifiqué tu jsfiddle para explicar el punto anterior.

También te recomiendo que revises esta página wiki para comprender las molestias de la herencia prototípica.


eche un vistazo al método $ broadcast : $ broadcast

De la documentación:

Despacha un nombre de evento hacia abajo a todos los ámbitos secundarios (y sus secundarios) notificando el ng. $ RootScope.Scope # $ registrado en los oyentes.


Use objetos en lugar de usar valores primitivos. En tu caso define un objeto como este

$scope.obj = {"value":"base"};

y prueba (obj.value). funcionará.


Eso sucede porque ngController crea un nuevo $ scope y la referencia de valor no es la misma. Puede resolver eso usando la propiedad $parent así:

<div ng-controller="BaseController"> <p>Base Controller Value: {{value}}</p> <div ng-controller="DerivedController"> <p>Derived Controller Value: {{$parent.value}}</p> </div> </div>

Y en DerivedController puede usar algo como eso: $scope.$parent.value

Pero la mejor manera de implementarlo es usar la sintaxis de controllerAs .

<div ng-controller="BaseController as BaseController "> <p>Base Controller Value: {{BaseController.value}}</p> <div ng-controller="DerivedController"> <p>Derived Controller Value: {{BaseController.value}}</p> </div>

Y en DerivedController puede usar algo como eso: $scope.BaseController.value

Eso le da al código más legibilidad, porque usted sabe a qué controlador se refiere. Más sobre esto en ngController Docs o en la sintaxis de "Controlador como" de Angular de ToddMotto


Cuando varios controladores necesitan acceder a los mismos datos, se debe usar un servicio . No debe confiar en la herencia del alcance, ya que restringe la forma en que puede escribir su HTML. Por ejemplo, en el futuro, decidió que DerivedController no debería ser hijo de BaseController.

Su servicio normalmente debe proporcionar una API pública y ocultar la implementación. Esto hace que sea más fácil refactorizar las partes internas.

HTML:

<div ng-controller="BaseController"> <p>Base Controller Value: {{model.getValue()}}</p> <button ng-click="model.updateValue(''Value updated from Base'')">Update In Base</button> <div ng-controller="DerivedController"> <p>Derived Controller Value: {{model.getValue()}}</p> <button ng-click="model.updateValue(''Value updated from Derived'')">Update In Derived</button> </div> </div>

JavaScript:

app.factory(''sharedModel'', function () { // private stuff var model = { value: "initial Value" }; // public API return { getValue: function() { return model.value; }, updateValue: function(value) { model.value = value; } }; }); function BaseController($scope, sharedModel) { $scope.model = sharedModel; } function DerivedController($scope, sharedModel) { $scope.model = sharedModel; }

Fiddle .

Además, no recomiendo usar $ rootScope para compartir entre los controladores.