AngularJS可以做的一件有趣的事情是将过滤器应用于特定的数据绑定表达式,这是一种应用的便捷方式,例如,特定于文化的货币或模型属性的日期格式。在范围上计算属性也很好。问题是这些功能都不适用于双向数据绑定方案 - 只是从范围到视图的单向数据绑定。这在一个优秀的图书馆中似乎是一个明显的遗漏 - 或者我错过了什么?
在KnockoutJS中,我可以创建一个读/写计算属性,它允许我指定一对函数,一个被调用以获取属性的值,另一个在属性时被调用。已设定。这允许我实现,例如,文化感知输入 - 让用户键入“$ 1.24”并将其解析为ViewModel中的浮点数,并在输入中反映ViewModel中的更改。
我能找到与此类似的最接近的事情是使用$scope.$watch(propertyName, functionOrNGExpression);
这允许我在$scope
中的属性发生变化时调用函数。但这并不能解决例如文化意识的输入问题。当我尝试修改$watched
方法本身中的$watch
属性时,请注意这些问题:
$scope.$watch("property", function (newValue, oldValue) {
$scope.outputMessage = "oldValue: " + oldValue + " newValue: " + newValue;
$scope.property = Globalize.parseFloat(newValue);
});
(http://jsfiddle.net/gyZH8/2/)
当用户开始输入时,输入元素会变得非常混乱。我通过将属性拆分为两个属性来改进它,一个用于未解析的值,另一个用于解析的值:
$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/)
这是对第一个版本的改进,但是有点冗长,并注意到范围更改的parsedValue
属性仍然存在问题(在第二个输入中键入内容,这会更改直接parsedValue
。注意顶部输入没有更新)。这可能发生在控制器操作或从数据服务加载数据中。
使用AngularJS是否有更简单的方法来实现此方案?我错过了文档中的一些功能吗?
答案 0 :(得分:230)
事实证明,这是一个非常优雅的解决方案,但它没有很好的记录。
格式化显示的模型值可由|
运算符和角度formatter
处理。事实证明,ngModel不仅包含格式化程序列表,还包含解析器列表。
ng-model
创建双向数据绑定<input type="text" ng-model="foo.bar"></input>
ngModel
控制器module.directive('lowercase', function() {
return {
restrict: 'A',
require: 'ngModel',
link: function(scope, element, attr, ngModel) {
...
}
};
});
link
方法中,将自定义转换器添加到ngModel
控制器function fromUser(text) {
return (text || '').toUpperCase();
}
function toUser(text) {
return (text || '').toLowerCase();
}
ngModel.$parsers.push(fromUser);
ngModel.$formatters.push(toUser);
ngModel
<input type="text" lowercase ng-model="foo.bar"></input>
这是一个working example,它将文本转换为input
中的小写,然后再转换为模型中的大写
API Documentation for the Model Controller还有一个简短的解释和其他可用方法的概述。