Uma das coisas interessantes que o AngularJS pode fazer é aplicar um filtro a uma expressão de ligação de dados específica, que é uma maneira conveniente de aplicar, por exemplo, moeda específica da cultura ou formatação de data das propriedades de um modelo. Também é bom ter propriedades computadas no escopo. O problema é que nenhum desses recursos funciona com cenários de ligação de dados bidirecionais - apenas ligação de dados unidirecional do escopo para a visualização. Parece uma omissão flagrante em uma biblioteca excelente - ou estou perdendo alguma coisa?
No KnockoutJS , eu poderia criar uma propriedade calculada de leitura / gravação, o que me permitiu especificar um par de funções, uma que é chamada para obter o valor da propriedade e outra que é chamada quando a propriedade é definida. Isso me permitiu implementar, por exemplo, entrada com reconhecimento de cultura - deixando o usuário digitar "$ 1,24" e analisá-lo em um carro alegórico no ViewModel e ter alterações no ViewModel refletidas na entrada.
A coisa mais próxima que eu poderia achar semelhante é o uso de $scope.$watch(propertyName, functionOrNGExpression);
Isso me permite ter uma função invocada quando uma propriedade nas $scope
alterações. Mas isso não resolve, por exemplo, o problema de entrada que reconhece a cultura. Observe os problemas quando tento modificar a $watched
propriedade dentro do $watch
próprio método:
$scope.$watch("property", function (newValue, oldValue) {
$scope.outputMessage = "oldValue: " + oldValue + " newValue: " + newValue;
$scope.property = Globalize.parseFloat(newValue);
});
( http://jsfiddle.net/gyZH8/2/ )
O elemento de entrada fica muito confuso quando o usuário começa a digitar. Eu a aprimorei dividindo a propriedade em duas propriedades, uma para o valor não analisado e outra para o valor analisado:
$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/ )
Isso foi uma melhoria em relação à primeira versão, mas é um pouco mais detalhada, e observe que ainda há um problema na parsedValue
propriedade das alterações do escopo (digite algo na segunda entrada, que altera parsedValue
diretamente. Observe que a entrada superior não atualizar). Isso pode acontecer a partir de uma ação do controlador ou do carregamento de dados de um serviço de dados.
Existe alguma maneira mais fácil de implementar esse cenário usando o AngularJS? Estou faltando alguma funcionalidade na documentação?
fonte
ngModelCtrl
$scope
diretamente, é para isso que o modelo será definido ... até que o usuário interaja com a caixa de texto. Nesse ponto, qualquer analisador pode afetar o valor do modelo. Além de um analisador, você pode adicionar um $ watch ao seu controlador para transformar o valor do modelo.