我是angular-input-modified指令的作者。
此指令用于跟踪模型的值,并允许检查值是否已修改,还提供reset()
函数以将值更改回初始状态。
现在,模型的初始值存储在ngModelController.masterValue
属性中,并提供了ngModelController.reset()
函数。请参阅the implementation。
我使用以下语句:eval('$scope.' + modelPath + ' = modelCtrl.masterValue;');
,以便将值恢复为其初始状态。 modelPath
这里实际上是ng-model
属性的值。这是开发的一种方式,我不喜欢这种方法,因为ng-model
值可能是一个复杂的值,嵌套的范围也会破坏这个功能。
重构此声明的最佳方法是什么?如何直接通过ngModel控制器界面更新模型的值?
答案 0 :(得分:2)
我到目前为止找到的最佳解决方案是使用$parse服务来解析ng-model
属性中的Angular表达式并检索它的setter函数。然后我们可以通过使用新值调用此setter函数来更改模型的值。
function reset () {
var modelValueSetter = $parse(attrs.ngModel).assign;
modelValueSetter($scope, 'Some new value');
}
这比eval()
更加可靠。
如果你有更好的主意,请提供另一个答案,或者只是评论一下。谢谢!
答案 1 :(得分:0)
[上一个回答]
我今天遇到了这个问题,我通过触发并使用闭包劫持$parsers
管道来解决它。
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( getViewValue(model) );
}
使用$setViewValue()
,您将触发$parsers
管道。我在第一个代码块中编写的函数将使用val = getViewValue(model)
执行,此时它将尝试根据其中的逻辑将其解析为用于$modelValue
的内容。但此时,闭包中的变量劫持了解析器并使用它完全覆盖当前的$ modelValue。
此时,val
中未使用$parser
,但它仍然是DOM中显示的实际值,因此请选择一个不错的值。
如果这种方法适合您,请告诉我。
<强> [编辑] 强>
似乎ngModel。$ commitViewValue也应该触发$ parsers管道,我快速尝试但无法使其工作。