funciones example eventos entre controladores comunicacion javascript angularjs scope

javascript - example - Angularjs observa cambio en el alcance de los padres.



funciones en angularjs (5)

De acuerdo, me tomó un tiempo, aquí están mis dos centavos, pero también me gusta la opción del evento:

Fiddle actualizado http://jsfiddle.net/enU5S/1/

El HTML

<div ng-app="myApp" ng-controller="MyCtrl"> <input type="text" model="model.someProperty"/> <div awesome-sauce some-data="model.someProperty"></div> </div>

El js

angular.module("myApp", []).directive(''awesomeSauce'',function($window){ return { restrict : "A", template: "<div>Ch-ch-ch-changes: {{count}} {{someData}}</div>", scope: {someData:"="}, link : function(scope,elem,attrs){ scope.count=0; scope.$watch("someData",function() { scope.count++; }) } }; }).controller("MyCtrl", function($scope){ $scope.model = {someProperty: "something here"); });

Lo que estoy mostrando aquí es que puede tener una variable que tiene una vinculación de dos vías entre el niño y el padre pero que no requiere que el niño llegue hasta su padre para obtener una propiedad. La tendencia a buscar cosas puede volverse loca si agrega un nuevo padre por encima de la directiva.

Si escribe en el cuadro actualizará el modelo en el controlador, esto a su vez está vinculado a la propiedad en la directiva para que se actualice en la directiva. Dentro de la función de enlace de directivas, tiene una configuración de reloj, por lo que cada vez que la variable de alcance cambia, incrementa un contador.

Vea más sobre el alcance del aislamiento y las diferencias entre usar = @ o & aquí: http://www.egghead.io/

Estoy escribiendo una directiva y necesito ver el alcance de los padres para un cambio. No estoy seguro si estoy haciendo esto de la manera preferida, pero no funciona con el siguiente código:

scope.$watch(scope.$parent.data.overlaytype,function() { console.log("Change Detected..."); })

Esto inició sesión en la carga de la ventana, pero nunca más, incluso cuando se cambia overlaytype.

¿Cómo puedo ver overlaytype para un cambio?

Edit: aquí está la directiva completa. No estoy completamente seguro de por qué tengo un niño alcance

/* Center overlays vertically directive */ aw.directive(''center'',function($window){ return { restrict : "A", link : function(scope,elem,attrs){ var resize = function() { var winHeight = $window.innerHeight - 90, overlayHeight = elem[0].offsetHeight, diff = (winHeight - overlayHeight) / 2; elem.css(''top'',diff+"px"); }; var watchForChange = function() { return scope.$parent.data.overlaytype; } scope.$watch(watchForChange,function() { $window.setTimeout(function() { resize(); }, 1); }) angular.element($window).bind(''resize'',function(e){ console.log(scope.$parent.data.overlaytype) resize(); }); } }; });


Debe tener la propiedad de datos en el ámbito de su hijo, los ámbitos utilizan la herencia prototípica entre los ámbitos padre e hijo.

Además, el primer argumento que espera el método $ watch es una expresión o una función para evaluar y no un valor de una variable. Por lo tanto, debe enviar eso.


Le sugiero que use la $ broadcast entre el controlador para realizar esto, que parece ser más la forma angular de comunicación entre los controladores padre / hijo

El concepto es simple: usted observa el valor en el controlador principal y luego, cuando se produce una modificación, puede transmitirlo y capturarlo en el controlador secundario.

Aquí hay un violín que lo demuestra: http://jsfiddle.net/DotDotDot/f733J/

La parte en el controlador principal se ve así:

$scope.$watch(''overlaytype'', function(newVal, oldVal){ if(newVal!=oldVal) $scope.$broadcast(''overlaychange'',{"val":newVal}) });

y en el controlador hijo:

$scope.$on(''overlaychange'', function(event, args){ console.log("change detected") //any other action can be perfomed here });

Buen punto con esta solución, si desea ver la modificación en otro controlador secundario, puede capturar el mismo evento

Que te diviertas

Edit: no te vi la última edición, pero mi solución también funciona con la directiva, actualicé el fiddle anterior ( http://jsfiddle.net/DotDotDot/f733J/1/ )

Modifiqué su directiva para forzarla a crear un ámbito secundario y crear un controlador:

directive(''center'',function($window){ return { restrict : "A", scope:true, controller:function($scope){ $scope.overlayChanged={"isChanged":"No","value":""}; $scope.$on(''overlaychange'', function(event, args){ console.log("change detected") //whatever you need to do }); }, link : function(scope,elem,attrs){ var resize = function() { var winHeight = $window.innerHeight - 90, overlayHeight = elem[0].offsetHeight, diff = (winHeight - overlayHeight) / 2; elem.css(''top'',diff+"px"); }; angular.element($window).bind(''resize'',function(e){ console.log(scope.$parent.data.overlaytype) resize(); }); } }; });


Si desea ver una propiedad de un ámbito primario, puede usar el método $watch del alcance primario.

//intead of $scope.$watch(...) $scope.$parent.$watch(''property'', function(value){/* ... */});

EDITAR 2016: Lo anterior debería funcionar bien, pero no es realmente un diseño limpio. Intente utilizar una directive o un component en su lugar y declare sus dependencias como enlaces. Esto debería llevar a un mejor rendimiento y un diseño más limpio.


Si está buscando ver una variable de alcance principal dentro de un alcance secundario, puede agregar true como segundo argumento en su $watch . Esto activará su reloj cada vez que se modifique su objeto.

$scope.$watch("searchContext", function (ctx) { ... }, true);