【发布时间】:2016-07-14 12:24:06
【问题描述】:
我的设置:Angular 1.4.4
我有一个看起来像这样的简单表格:
<div ng-controller="MyCtrl3">
<datepick ng-model="model.carA" foo3="model.carB"></datepick>
<datepick ng-model="model.carB" foo3="model.carA"></datepick>
<pre> {{ model | json }} </pre>
</div>
datepick 指令如下所示:
myApp.directive('datepick', function() {
return {
restrict: 'E',
scope: {
ngModel: '='
},
template: '<div ng-if="true"><input type="text" ng-model="ngModel.bar"/></div>'
};
});
所以我使用ng-model 属性将具有bar 属性的对象传递给它。到目前为止,一切都按预期工作。模型与呈现形式的变化同步。
下一步我想引入验证以验证当前指令的基础模型上的属性 bar 以及 MyCtrl3 - model 中的一些其他对象。为此,我创建了属性指令foo3:
myApp.directive('foo3', function() {
return {
restrict: 'A',
require: "ngModel",
link: function(scope, element, attrs, controller) {
scope.$watch(attrs.foo3, function(newValue, oldValue) {
// New Value of comparison field
console.log("New valued for comparison model: " + JSON.stringify(newValue));
// Current value of undelying movelValue
console.log("Current value for undelying model" + JSON.stringify(controller.$modelValue));
controller.$validate();
}, true);
var validateMoreThanDate = function(modelValue, viewValue) {
let viewValueObject = modelValue;
var comparisonModel = scope.$eval(attr.moreThanDateObject);
if ((!viewValueObject && !viewValueObject.bar) ||
(!comparisonModel && !comparisonModel.bar)) {
// It's valid because we have nothing to compare against
return true;
}
// It's valid if model is lower than the model we're comparing against
return viewValueObject.bar > comparisonModel.bar;
};
controller.$validators['moreThanDateObject'] = validateMoreThanDate;
}
};
});
如您所见,我将模型作为参数传递给指令foo3。观察者跟踪每一个变化,但模型变化时不会触发验证器。
问题:如何验证我的案例中的这些字段? (这里正在使用 jsFiddle 检查实时代码:https://jsfiddle.net/ichyr/b1jqfkj1/)
注意我知道当对象中的模型和该对象的属性发生变化时,不会触发 $parsers 和 $formatters 管道:
如果新值是一个对象(而不是字符串或数字),我们 应该在将对象传递给 $setViewValue 之前制作对象的副本。 这是因为 ngModel 不执行对象的深度监视,它 只寻找身份的改变。如果只更改属性 对象然后 ngModel 将不会意识到该对象有 已更改并且不会调用 $parsers 和 $validators 管道。
所以也许 $validators 也没有被触发,但是在 $watch 表达式中添加 controller.$validate() 并没有帮助。
【问题讨论】:
标签: javascript angularjs forms validation