change javascript angularjs data-binding angularjs-scope

javascript - change - ng-model



¿Cómo hacer un filtrado bidireccional en AngularJS? (1)

Una de las cosas interesantes que AngularJS puede hacer es aplicar un filtro a una expresión de enlace de datos particular, que es una forma conveniente de aplicar, por ejemplo, el formato de moneda o fecha específico de la cultura de las propiedades de un modelo. También es bueno tener propiedades calculadas en el alcance. El problema es que ninguna de estas características funciona con escenarios de enlace de datos bidireccionales, solo un enlace de datos de una vía desde el alcance hasta la vista. Esto parece ser una omisión flagrante en una biblioteca por lo demás excelente, ¿o me estoy perdiendo algo?

En KnockoutJS , pude crear una propiedad calculada de lectura / escritura, que me permitió especificar un par de funciones, una que se llama para obtener el valor de la propiedad, y otra a la que se llama cuando se establece la propiedad. Esto me permitió implementar, por ejemplo, entradas con reconocimiento de cultura, permitiendo al usuario escribir "$ 1.24" y analizarlo en un flotante en el modelo de vista, y tener reflejos en el modelo de vista en la entrada.

Lo más parecido que pude encontrar es el uso de $scope.$watch(propertyName, functionOrNGExpression); Esto me permite tener una función invocada cuando cambia una propiedad en $scope . Pero esto no resuelve, por ejemplo, el problema de entrada a la cultura. Observe los problemas cuando trato de modificar la propiedad $watched dentro del método $watch sí:

$scope.$watch("property", function (newValue, oldValue) { $scope.outputMessage = "oldValue: " + oldValue + " newValue: " + newValue; $scope.property = Globalize.parseFloat(newValue); });

( http://jsfiddle.net/gyZH8/2/ )

El elemento de entrada se confunde mucho cuando el usuario comienza a escribir. Lo mejoré al dividir la propiedad en dos propiedades, una para el valor no analizado y otra para el valor analizado:

$scope.visibleProperty= 0.0; $scope.hiddenProperty = 0.0; $scope.$watch("visibleProperty", function (newValue, oldValue) { $scope.outputMessage = "oldValue: " + oldValue + " newValue: " + newValue; $scope.hiddenProperty = Globalize.parseFloat(newValue); });

( http://jsfiddle.net/XkPNv/1/ )

Esto fue una mejora con respecto a la primera versión, pero es un poco más detallado y observa que todavía existe un problema con la propiedad parsedValue de los cambios en el alcance (escriba algo en la segunda entrada, que cambia el valor parsedValue directamente. no se actualiza). Esto podría suceder a partir de una acción del controlador o de cargar datos desde un servicio de datos.

¿Hay alguna manera más fácil de implementar este escenario usando AngularJS? ¿Me falta algo de funcionalidad en la documentación?


Resulta que hay una solución muy elegante para esto, pero no está bien documentada.

El formato de los valores de modelo para visualización puede ser manejado por | operador y un formatter angular. Resulta que el ngModel no solo tiene una lista de formateadores sino también una lista de analizadores sintácticos.

1. Use ng-model para crear el enlace de datos bidireccional

<input type="text" ng-model="foo.bar"></input>

2. Cree una directiva en su módulo angular que se aplicará al mismo elemento y que depende del controlador ngModel

module.directive(''lowercase'', function() { return { restrict: ''A'', require: ''ngModel'', link: function(scope, element, attr, ngModel) { ... } }; });

3. Dentro del método de link , agregue sus conversores personalizados al controlador ngModel

function fromUser(text) { return (text || '''').toUpperCase(); } function toUser(text) { return (text || '''').toLowerCase(); } ngModel.$parsers.push(fromUser); ngModel.$formatters.push(toUser);

4. Agregue su nueva directiva al mismo elemento que ya tiene el ngModel

<input type="text" lowercase ng-model="foo.bar"></input>

Aquí hay un ejemplo de trabajo que transforma el texto a minúsculas en la input y de nuevo a mayúsculas en el modelo

La documentación de API para el controlador de modelo también tiene una breve explicación y una descripción general de los otros métodos disponibles.