¿Cómo suscribirse al cambio de propiedad cuando se usa la controller as
sintaxis?
controller('TestCtrl', function ($scope) {
this.name = 'Max';
this.changeName = function () {
this.name = new Date();
}
// not working
$scope.$watch("name",function(value){
console.log(value)
});
});
<div ng-controller="TestCtrl as test">
<input type="text" ng-model="test.name" />
<a ng-click="test.changeName()" href="#">Change Name</a>
</div>
Respuestas:
Solo vincula el contexto relevante.
Ejemplo: http://jsbin.com/yinadoce/1/edit
ACTUALIZAR:
La respuesta de Bogdan Gersak es realmente equivalente, ambas respuestas intentan vincularse
this
con el contexto correcto. Sin embargo, encontré su respuesta más limpia.Dicho esto, en primer lugar, debe comprender la idea subyacente detrás de esto .
ACTUALIZACIÓN 2:
Para aquellos que usan ES6, al usarlo
arrow function
obtienes una función con el contexto correcto OOTB.Ejemplo
fuente
$scope
para usted es un tipo de servicio que proporciona este tipo de métodos.name
en sereturn this.name;
refiere al nombre del controlador o la propiedad "name
" aquí?angular.bind
devuelve una función con un contexto acotado (arg # 1). En nuestro caso, vinculamosthis
, que es la instancia del controlador, a la función (arg # 2), por lo quethis.name
significa la propiedadname
de la instancia del controlador.Usualmente hago esto:
fuente
$scope.$watch
y usar esa función para devolver un valor del cierre. Todavía tengo que encontrar otro ejemplo de esto, pero funciona y es el mejor. La razón por la que no elegí la respuesta a continuación (es decir,$scope.$watch('test.name', function (value) {});
) es porque requería que codificara lo que denominé mi controlador en mi plantilla o en $ stateProvider de ui.router y cualquier cambio que se produzca rompería el observador sin darse cuenta.angular.bind
) es si desea vincularsethis
o simplemente agregar otra referenciathis
dentro del cierre. Estos son funcionalmente equivalentes, y, en mi experiencia, este tipo de elección es a menudo una llamada subjetiva y el asunto de una opinión muy fuerte.$scope.$watch( ()=> { return this.name' }, function(){} )
Flecha gorda al rescate() => this.name
$scope.$watchCollection
y aún obtener losoldVal, newVal
parámetros?Puedes usar:
Esto está trabajando JSFiddle con su ejemplo.
fuente
De manera similar al uso de la "prueba" de "TestCtrl como prueba", como se describe en otra respuesta, puede asignar "self" a su alcance:
De esta manera, no está vinculado al nombre especificado en el DOM ("TestCtrl como prueba") y también evita la necesidad de vincular (esto) a una función.
... para usar con el html original especificado:
fuente
$scope
es un servicio, así que si agregamos$scope.self = this
, en otro controlador si hacemos lo mismo, ¿qué pasará allí?AngularJs 1.5 admite el valor predeterminado $ ctrl para la estructura ControllerAs.
fuente
en realidad puede pasar una función como primer argumento de un $ watch ():
Lo que significa que podemos devolver nuestra referencia this.name:
Lea una publicación interesante sobre el tema controllerAs https://toddmotto.com/digging-into-angulars-controller-as-syntax/
fuente
Puede usar el ciclo de vida del componente angular $ onChanges .
ver documentación aquí: https://docs.angularjs.org/guide/component en la sección de aplicación basada en componentes
fuente
Escribir un $ watch en la sintaxis de ES6 no fue tan fácil como esperaba. Esto es lo que puedes hacer:
fuente
NOTA : Esto no funciona cuando View y Controller están acoplados en una ruta o a través de un objeto de definición de directiva. Lo que se muestra a continuación solo funciona cuando hay un "SomeController as SomeCtrl" en el HTML. Al igual que Mark V. señala en el comentario a continuación, y tal como él dice, es mejor hacer lo que Bogdan hace.
Yo uso:
var vm = this;
al comienzo del controlador para quitar la palabra "this" de mi camino. Entoncesvm.name = 'Max';
y en el reloj yoreturn vm.name
. Yo uso el "vm" al igual que @Bogdan usa "self". Esta var, ya sea "vm" o "self", es necesaria ya que la palabra "this" toma un contexto diferente dentro de la función. (por lo que devolver this.name no funcionaría) Y sí, debe inyectar $ scope en su hermosa solución "controlador como" para llegar a $ watch. Consulte la Guía de estilo de John Papa: https://github.com/johnpapa/angularjs-styleguide#controllersfuente
Así es como se hace esto sin $ scope (y $ watch!) Los 5 errores principales: abuso de reloj
Si está utilizando la sintaxis "controlador como", es mejor y más limpio evitar usar $ scope.
Aquí está mi código en JSFiddle . (Estoy usando un servicio para mantener el nombre; de lo contrario, el conjunto ES5 Object.defineProperty y los métodos get causan llamadas infinitas.
fuente