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