2016-07-27 69 views
2

我想写一个自定义指令来验证输入值:它是否属于指定的范围。问题是如果不知道用于ng-model的范围变量的名称,我就无法访问ng-model。考虑到该指令必须重复使用不同的输入,我想直接访问ng-model。我确实尝试使用scope[attrs.ngModel],但得到undefined值。如何在指令内读取ng-model值?谢谢。如何从属性指令访问ng-model?

netupApp.directive('between', function() { 
return { 
    restrict: 'A', 
    require: 'ngModel', 
    link: function(scope, element, attrs, ngModelCtrl) { 
     scope.$watch('dataSubmitting', function(dataSubmitting){ 
      if (dataSubmitting) { 
       var min = Number(attrs.min); 
       var max = Number(attrs.max); 
       console.log(attrs.ngModel); // "number" 
       console.log(scope[attrs.ngModel]); // undefined 
       var inputText = scope.number; // that is the var used in ng-model 
       console.log(min); // 10 
       console.log(inputText); // would be the input value 
       console.log(max); //20 
       if (inputText <= min || inputText >= max) { 
        scope.alerts.push({ 
         msg: 'error', 
         type: 'danger', 
         icon: 'warning', 
         'closable': true 
        }); 
       } 
      } 
     }); 
    } 
}; 
}); 
+0

为什么你是否需要访问范围(因为你没有)? – dfsq

+0

@dfsq也许有更好的解决方案,我不知道:)我必须编写一些自定义指令来验证输入值,他们应该检查提交操作后的值(没有表单,只是输入),并推送警报msg到示波器的警报数组。 – Georgy

+1

理想指令不需要知道任何有关范围,名称等的信息。它也不需要管理错误消息,这些都应该是控制器/模板的责任。指令不应该决定是否有错误。什么指令必须做只是检查什么是有效性状态。 – dfsq

回答

1

你应该挂钩到角度验证系统,并添加您的验证功能,无论是$验证或$ asyncValidators集合(在你的情况,我认为$验证就足够了,没有必要异步)。

的验证函数接受模型值作为参数:

link: function(scope, elm, attrs, ctrl) { 

    var min = Number(attrs.min); 
    var max = Number(attrs.max); 

    ctrl.$validators.between = function(modelValue, viewValue) { 
     if (modelValue <= min || modelValue >= max) { 
      //do something here or just return false 
      return false; 
     } 
     return true; 
    } 

} 

在视图中,可以得到这样的验证错误消息:

<div ng-messages="formName.inputName.$error"> 
    <p ng-message="between">The value is not in the required range<p> 
</div> 

参考文档:https://docs.angularjs.org/api/ng/type/ngModel.NgModelController

+0

谢谢。将这个标记为公认的答案,因为它建议更好的(适当的)解决方案。 – Georgy

+0

谢谢!当然,为什么在已经有机制进行验证的情况下重新发明轮子? –

1

正确的方式来获得ngModel.$viewValue是:

app.directive('between', function() { 
    return { 
    require: 'ngModel', 
    link: function (scope, element, attrs, ngModel) { 

     ngModel.$render = function() { 
      var newValue = ngModel.$viewValue; 
      console.log(newValue) 
     }; 

    } 
    }; 
}); 

看一看教程下面想从directive

https://egghead.io/lessons/angularjs-using-ngmodel-in-custom-directives

+0

谢谢。我看到这个教程,但无法得到结果,也许有一些初始化问题,现在一切正常。 – Georgy

0

调用ngModel.$setViewVAlue据angluarJs时doc:$parse 您需要解析ËATTRS,请尝试:

var getter=$parse(attrs.ngModel); 
var setter=getter.assign; 
setter(scope,getter(scope)); 
+0

不要误解我的意思,但我认为这更多的是一个肮脏的伎俩,不认为这应该是默认的解决方案。感谢您的帮助! – Georgy