我正在尝试连接适配器以启用ASP.Net MVC为客户端验证发出的标记在AngularJS中工作,并且我遇到了一个有趣的障碍。如果我通过指令编译函数动态添加required
属性:
var myApp = angular.module('myApp', []).directive('valRequired', function() {
return {
compile: function (element) {
element.attr('required', 'required');
return function() { /* other custom logic here */ }
}
};
});
select
元素不会根据需要进行验证。在动态添加属性(jsFiddle)时,它似乎只是一个问题。
澄清:我想按原样使用MVC的@Html.TextBoxFor(...)
。对于基于DataAnnotations的模型,它发出的data-val-*
属性包含有关运行哪些验证以及错误消息应该是什么的信息。我不是在寻找帮助连接错误消息,我只需要能够连接一个告诉input
,select
等的指令来使用required
验证
答案 0 :(得分:1)
让我先说这个并不漂亮,但它确实有效。我尝试了不同的方法来使本机指令工作,但无济于事。看起来这个指令执行时已经太晚了。
这将查找您的data-val-required属性并向元素添加验证。
它会触发所有相同的内容,因此myForm.mySelect.$valid
仍可以myForm.mySelect.$error.required
http://jsfiddle.net/TheSharpieOne/knc8p/
var myApp = angular.module('myApp', []).directive('valRequired', function () {
return {
require: 'ngModel',
restrict: 'A',
link: function (scope, elm, attr, ctrl) {
if (!ctrl || !attr.valRequired) return;
attr.required = true; // force truthy in case we are on non input element
var validator = function (value) {
if (attr.required && (value == '' || value === false)) {
ctrl.$setValidity('required', false);
return;
} else {
ctrl.$setValidity('required', true);
return value;
}
};
ctrl.$formatters.push(validator);
ctrl.$parsers.unshift(validator);
attr.$observe('required', function () {
validator(ctrl.$viewValue);
});
}
};
});
function MyCtrl($scope, $http) {
$scope.model = {
property: ''
};
}
答案 1 :(得分:0)
<强>更新强> 我想到了一个更好的方法来回答这个问题。旧答案低于新答案。
您可以获得对AngularJS所需指令的引用,并将其应用于您自己的指令。下面是一个代码示例:
var myApp = angular.module('myApp', []).directive('valRequired', function(requiredDirective) {
var newDirective = {},
angularDirective = requiredDirective[0]; //This assumes angular's required directive is the first one
//Copy over all other properties of the angular directive
angular.extend(newDirective, angularDirective);
//Change the name of our directive back to valRequired
newDirective.name = 'valRequired';
//Provide our own logic in the linking function
newDirective.link = function(scope, element, attr, ctrl){
//Super call
angularDirective.link.apply(this, arguments);
if(attr.valRequired === 'required'){
attr.$set('ngRequired', 'true');
} else {
attr.$set('ngRequired', 'false');
}
}
return newDirective;
});
<input data-val-required="required" ng-model="foo" />
OLD ANSWER
使用jQuery或jQLite的attr()
方法不会更改AngularJs' Attributes object。 Attributes对象是指令用作其逻辑值的值。
您还需要包含ng-required属性,尽管您不需要将任何角度表达式绑定到它。这个问题可以帮到你: Html5 data-* with asp.net mvc TextboxFor html attributes
原因是我们需要强制angular将指令应用于此节点。在模板的编译阶段之后更新属性不会通知angular将新指令应用于节点。
这应该有效:
var myApp = angular.module('myApp', []).directive('valRequired', function() {
return {
priority : 101, //The priority needs to run higher than 100 to get around angularjs' default priority for ngRequired
link: function (scope, element, attr) {
if(attr.valRequired === 'true'){
attr.$set('ngRequired', 'true');
} else {
attr.$set('ngRequired', 'false');
}
}
};
});
<input ng-required data-val-required="true" ng-model="foo" />