我正在编写一个需要ngModel的指令,并添加格式化程序和解析器来操作该值。它工作得很好,但由于操作依赖于外部数据,我必须观看,我正在寻找一种方法来更新这款手表的模型值。我试着调用$setViewValue
但没有任何反应(因为$ viewValue没有改变??)。
在下面的简单示例中,对“factor”的更改不会更新模型值:
angular.module('app', []).directive('multiply', multiplyDirective);
function multiplyDirective() {
return {
restrict: 'A',
require: 'ngModel',
scope: {
factor: '=multiply'
},
link: function(scope, elem, attr, ngModel) {
ngModel.$formatters.push(function (value) {
return value / scope.factor;
});
ngModel.$parsers.push(function (value) {
return value * scope.factor;
});
scope.$watch('factor', function () {
// how to run the parsers pipeline to update modelvalue?
ngModel.$setViewValue(ngModel.$viewValue);
});
}
}
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.6/angular.min.js"></script>
<body ng-app ng-init="factor = 1; value = 1">
<input type="number" ng-model="value" multiply="factor" /> x
<input type="number" ng-model="factor" />
= {{ value }}
</body>
编辑:如果我调用内部$$parseAndValidate
方法,它会起作用,但我想知道是否有公共API来强制执行更新。
修改:我发现ngModel.$setViewValue(ngModel.$viewValue);
中1.3.0
的行为发生了变化。使用1.2.x
代码可以使用!
答案 0 :(得分:1)
有点晚了,但我已经描述了你如何做到这一点here。这适用于AngularJS 1.6.x
基本上,您可以使用$parsers pipeline
触发$setViewValue()
。
下面是一个代码片段,允许您通过“劫持”$ parsers管道以编程方式将ngModel设置为您喜欢的任何内容。这是使用闭包来完成的。
使用这样的闭包设置$解析器:
const hijack = {trigger: false; model: null};
modelCtrl.$parsers.push( val => {
if (hijack.trigger){
hijack.trigger = false;
return hijack.model;
}
else {
// .. do something else ...
})
然后,为了(重新)设置模型,您需要通过$viewValue
更改modelCtrl.$setViewValue('newViewValue')
来触发管道。 (是的,新视图值必须与当前值不同)。
const $setModelValue = function(model){
// trigger the hijack and pass along your new model
hijack.trigger = true;
hijack.model = model;
// assuming you have some logic in getViewValue to output a viewValue string
modelCtrl.$setViewValue( "some new view value" );
}
答案 1 :(得分:0)
根本没有加载你的指令。您需要将模块名称提供给ng-app,如<body ng-app="app">
。然后,只要修改了因子,就可以调用ngModel.$setViewValue(ngModel.$viewValue)
。
angular.module('app', []).directive('multiply', multiplyDirective);
function multiplyDirective() {
return {
restrict: 'A',
require: 'ngModel',
scope: {
factor: '=multiply'
},
link: function(scope, elem, attr, ngModel) {
ngModel.$formatters.push(function (value) {
return value / scope.factor;
});
ngModel.$parsers.push(function (value) {
return value * scope.factor
});
scope.$watch('factor', function () {
// how to run the parsers pipeline to update modelvalue?
ngModel.$setViewValue(ngModel.$viewValue);
});
}
}
}
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<body ng-app="app" ng-init="factor = 1; value = 1">
<input type="number" ng-model="value" multiply="factor" /> x
<input type="number" ng-model="factor" />
= {{ value }}
</body>
&#13;
答案 2 :(得分:0)
从v1.3.18的来源,我看不到公开的api。管道来自 $$ parseAndValidate 方法,该方法也是从 $ commitViewValue 调用的(需要提交/设置不同的值,否则它将return)