在Angular.js

时间:2016-02-10 07:22:26

标签: angularjs forms angularjs-directive angular-ngmodel

我是angular-input-modified指令的作者。

此指令用于跟踪模型的值,并允许检查值是否已修改,还提供reset()函数以将值更改回初始状态。

现在,模型的初始值存储在ngModelController.masterValue属性中,并提供了ngModelController.reset()函数。请参阅the implementation

我使用以下语句:eval('$scope.' + modelPath + ' = modelCtrl.masterValue;');,以便将值恢复为其初始状态。 modelPath这里实际上是ng-model属性的值。这是开发的一种方式,我不喜欢这种方法,因为ng-model值可能是一个复杂的值,嵌套的范围也会破坏这个功能。

重构此声明的最佳方法是什么?如何直接通过ngModel控制器界面更新模型的值?

2 个答案:

答案 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管道,我快速尝试但无法使其工作。