所以,我已经花了约4个小时这一点。我所试图实现的是一个自定义的指令,类似于NG-需要有一个输入并执行验证。以下是NG-需要code。
VAR requiredDirective =功能(){ 返回{ 限制:'A', 要求:'?ngModel', 链接:功能(范围,榆树,ATTR,CTRL){ 如果(CTRL!)回报; attr.required = TRUE; //力truthy情况下,我们都是非输入元素 Ctrl键。$ validators.required =功能(modelValue,viewValue){ 回报!attr.required || !CTRL $的isEmpty(viewValue); }; ATTR。观察$('需要',函数(){ CTRL $的validate()。 }); } };};
我知道,当需要的属性更改它的价值,我们将再次做验证。说,如果你有
<输入NG-模式=sor.sealNG-模式选项={updateOn:默认模糊'}类=表格控NG-所需=sor.sealUwatType =='海豹'TYPE =文本占位=输入一个SEAL / UWAT IDID =海豹NAME =印章/>
它是如何添加属性的 =需要必需的的时候NG-前需要pression是真的吗?它是如何删除属性时,NG-前需要pression是假的?
解决方案角创建一个内部上的所有的布尔属性等同的如 NG-要求,NG-检查,NG-停用
等...
来源
VAR BOOLEAN_ATTR = {};的forEach('多,选择,确认,残疾人,只读,必需open'.split(''),功能(价值){ BOOLEAN_ATTR [小写(值)] =价值;});
和对这些进行注册属性的通用拨动通用连接功能。
来源
的forEach(BOOLEAN_ATTR,功能(作为propName,attrName){ //绑定到多个不支持 如果(==的propName多重)回报; 功能defaultLinkFn(范围,元素,属性){ 范围。$腕表(ATTR [标准化],功能ngBooleanAttrWatchAction(值){ 。ATTR $集(attrName,!!值); }); } 无功归一化= directiveNormalize('NG-'+ attrName); VAR linkFn = defaultLinkFn; 如果(===的propName'检查'){ linkFn =功能(范围,元素,属性){ //确保ngChecked不与ngModel干扰时两者都在相同的输入设定 如果(attr.ngModel!== ATTR [标准化]){ defaultLinkFn(范围,元素,属性); } }; } ngAttributeAliasDirectives [标准化] =功能(){ 返回{ 限制:'A', 优先权:100, 链接:linkFn }; };});
所以基本上 NG-要求
添加属性要求
本身在内部登记作为指令,做的为 NG-模型验证
。
您可以通过输出验证这是什么 ngRequired
指令实际持有,它拥有2指令配置,一种具有优先级100(其中前NG-模式运行),设定/重置是在元素和另一个具有与NG-模型和验证验证挂钩上的属性。
的.config(函数($提供){ $ provide.decorator('ngRequiredDirective',函数($代表){ 的console.log($代表); //检查控制台上的配置,你会看到2配置阵列 返回$代表; })});
这是创建2配置为相同的指令选择的好,例如:
\r\r
angular.module(应用,[])。指令(MYDIR ,函数(){\r 返回{\r 限制:'A',\r 链接:功能(){\r 的console.log(A);\r }\r }\r})指令(MYDIR',函数(){\r 返回{\r 限制:'A',\r 链接:功能(){\r 的console.log(B);\r }\r }\r})。配置(函数($提供){\r $ provide.decorator('myDirDirective',函数($代表){\r 的console.log($代表); //检查控制台上的配置,你会看到2配置阵列\r 返回$代表;\r })\r});
\r
&LT;脚本SRC =https://ajax.googleapis.com/ajax /libs/angularjs/1.3.15/angular.min.js\"></script>\r&LT; DIV NG-应用=应用程序&GT;\r\r &LT; DIV我-DIR&GT;&LT; / DIV&GT;\r&LT; / DIV&GT;
\r\r\r
So I have spent about 4 hours on this already. What I am trying to achieve is a custom directive that is similar to ng-required which has an input and does the validation. Following is the ng-required code.
var requiredDirective = function() {
return {
restrict: 'A',
require: '?ngModel',
link: function(scope, elm, attr, ctrl) {
if (!ctrl) return;
attr.required = true; // force truthy in case we are on non input element
ctrl.$validators.required = function(modelValue, viewValue) {
return !attr.required || !ctrl.$isEmpty(viewValue);
};
attr.$observe('required', function() {
ctrl.$validate();
});
}
};
};
I know when the required attribute changes it's value, we will do validation again. Say if you have
<input
ng-model="sor.seal"
ng-model-options="{ updateOn : 'default blur' }"
class="form-control"
ng-required="sor.sealUwatType=='SEAL'"
type="text"
placeholder="Enter a SEAL/UWAT ID"
id="seal"
name="seal"
/>
How does it add an attribute required="required" when the ng-required expression is true? And How does it remove the attribute when the ng-required expression is false?
解决方案Angular creates an internal ng-attribute Alias directive on all the boolean attribute equivalents like ng-required, ng-checked, ng-disabled
etc...
Source
var BOOLEAN_ATTR = {};
forEach('multiple,selected,checked,disabled,readOnly,required,open'.split(','), function(value) {
BOOLEAN_ATTR[lowercase(value)] = value;
});
and the generic link function registered on these performs a generic toggling of attributes
Source
forEach(BOOLEAN_ATTR, function(propName, attrName) {
// binding to multiple is not supported
if (propName == "multiple") return;
function defaultLinkFn(scope, element, attr) {
scope.$watch(attr[normalized], function ngBooleanAttrWatchAction(value) {
attr.$set(attrName, !!value);
});
}
var normalized = directiveNormalize('ng-' + attrName);
var linkFn = defaultLinkFn;
if (propName === 'checked') {
linkFn = function(scope, element, attr) {
// ensuring ngChecked doesn't interfere with ngModel when both are set on the same input
if (attr.ngModel !== attr[normalized]) {
defaultLinkFn(scope, element, attr);
}
};
}
ngAttributeAliasDirectives[normalized] = function() {
return {
restrict: 'A',
priority: 100,
link: linkFn
};
};
});
So basically ng-required
adds the attribute required
which itself is registered internally as a directive that does the validation for ng-model
.
You can verify this by outputting what ngRequired
directive actually holds, it holds 2 directive configurations, one with priority 100 (which runs before ng-model), which sets/resets the attribute on the element it is upon and another one which has the validation hook with the ng-model and validators.
.config(function($provide) {
$provide.decorator('ngRequiredDirective', function($delegate) {
console.log($delegate); //Check the console on the configuration you will see array of 2 configurations
return $delegate;
})
});
This is as good as creating 2 configurations for same directive selector, example:
angular.module('app', []).directive('myDir', function() {
return {
restrict: 'A',
link: function() {
console.log("A");
}
}
}).directive('myDir', function() {
return {
restrict: 'A',
link: function() {
console.log("B");
}
}
}).config(function($provide) {
$provide.decorator('myDirDirective', function($delegate) {
console.log($delegate); //Check the console on the configuration you will see array of 2 configurations
return $delegate;
})
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js"></script>
<div ng-app="app">
<div my-dir></div>
</div>