AngularJS 自定义指令未删除 child 元素中的 ng-required 指令
AngularJS custom directive not deleting ng-required directive in child elements
在将 ng-required
指令引入 child div.
之前,下面的指令工作正常
即使元素已被删除,ng-model
属性 在表单中仍然是必需的。结果是用户需要填写表单中不存在的字段才能提交。
我们针对此指令(由不再在公司工作的人制定)的当前 patch-job 解决方案是在与自定义指令相同的元素上引入 ng-if
指令。这显然违背了自定义指令的目的,现在我需要添加更多条件,需要修复。
我已阅读其他帖子,认为该问题与指令范围有关。但是,我已经尝试使用范围级别选项并在控制台中注销范围以查找 destroy-style 方法但没有成功。
在商业广告看到视图的情况下,由于用户级别为 3,他将正确地看到下面的 html。但是要求仍然存在...
自定义指令:
angular.module('tvalorApp').directive('checkPermissions', ['PermissionsServices', function(PermissionsServices) {
return {
restrict: 'A',
scope: {
level:'@'
},
link: function(scope, elem, attrs, ctrl) {
function checkPermission() {
if (attrs.permissions != '') {
var hasPermission = PermissionsServices.hasAccess(attrs.checkPermissions, scope.level);
if (!hasPermission) {
console.log(scope)
elem.remove();
}
} else {
elem.remove();
}
}
scope.$watch('level', function(value) {
checkPermission();
});
}
};
}]);
指令使用的工厂:
angular.module('tvalorApp').factory('PermissionsServices', PermissionsServices);
function PermissionsServices() {
var fields = {
"noAdmin": [false, true, true],
"noValidator": [true, false, true],
"noCommercial": [true, true, false],
"onlyAdmin": [true, false, false],
"onlyValidator": [false, true, false],
"onlyCommercial": [false, false, true],
"allUsers": [true, true, true],
"noUsers": [false, false, false],
};
var readOnlyFields = {
"protectAdmin": [true, false, false],
"protectValidator": [false, true, false],
"protectCommercial": [false, false, true],
"noProtectAdmin": [false, true, true],
"noProtectValidator": [true, false, true],
"noProtectCommercial": [true, true, false],
"noProtect": [false, false, false],
"protectAll": [true, true, true],
};
var hasAccess = function(stateName, level) {
var hasAccess = false,
level = level - 1;
if(fields[stateName][level]) {
hasAccess = true;
}
return hasAccess;
};
var checkReadOnlyField = function(fieldName, level) {
return readOnlyFields[fieldName][level - 1];
}
return {
hasAccess: hasAccess,
checkReadOnlyField: checkReadOnlyField
};
};
HTML:
<div class="form-group" level="{{taskCtrl.level}}" check-permissions="noCommercial">
<label for="a_market">
Situación del mercado <span class="highlight">*</span>
</label>
<select id="a_market" name="a_market" class="form-control" ng-change="taskCtrl.setEditTask()"
ng-options="item.id as item.es for item in mainCtrl.market" ng-model="taskCtrl.task.a_id_market"
ng-required="true">
<option value="">N.A.</option>
</select>
<p class="error-message" ng-show="taskForm.a_market.$dirty && taskForm.a_market.$error.required">Campo
Obligatorio</p>
</div>
这里的问题是,当自定义指令删除 div 元素时,表单控件仍然注册到父表单。
一种解决方案是在删除元素时使用 $removeControl(control);
方法注销该控件。 (documentation)
为了实现这一点,首先您需要将父表单引用注入到自定义指令中:
require: '^form',
和控件名称,例如:
scope: {
level: '@',
field: '@'
},
现在在 link 函数中,您可以访问父表单:
link: function(scope, elem, attrs, ctrl) {
console.log('parent form', ctrl);
...
}
您可以注销被删除的控件:
if (!hasPermission) {
elem.remove();
ctrl.$removeControl(ctrl[scope.field]);
}
添加这些元素后,当元素被删除时,表单就可以提交了。
这是一个工作示例:DEMO
在将 ng-required
指令引入 child div.
即使元素已被删除,ng-model
属性 在表单中仍然是必需的。结果是用户需要填写表单中不存在的字段才能提交。
我们针对此指令(由不再在公司工作的人制定)的当前 patch-job 解决方案是在与自定义指令相同的元素上引入 ng-if
指令。这显然违背了自定义指令的目的,现在我需要添加更多条件,需要修复。
我已阅读其他帖子,认为该问题与指令范围有关。但是,我已经尝试使用范围级别选项并在控制台中注销范围以查找 destroy-style 方法但没有成功。
在商业广告看到视图的情况下,由于用户级别为 3,他将正确地看到下面的 html。但是要求仍然存在...
自定义指令:
angular.module('tvalorApp').directive('checkPermissions', ['PermissionsServices', function(PermissionsServices) {
return {
restrict: 'A',
scope: {
level:'@'
},
link: function(scope, elem, attrs, ctrl) {
function checkPermission() {
if (attrs.permissions != '') {
var hasPermission = PermissionsServices.hasAccess(attrs.checkPermissions, scope.level);
if (!hasPermission) {
console.log(scope)
elem.remove();
}
} else {
elem.remove();
}
}
scope.$watch('level', function(value) {
checkPermission();
});
}
};
}]);
指令使用的工厂:
angular.module('tvalorApp').factory('PermissionsServices', PermissionsServices);
function PermissionsServices() {
var fields = {
"noAdmin": [false, true, true],
"noValidator": [true, false, true],
"noCommercial": [true, true, false],
"onlyAdmin": [true, false, false],
"onlyValidator": [false, true, false],
"onlyCommercial": [false, false, true],
"allUsers": [true, true, true],
"noUsers": [false, false, false],
};
var readOnlyFields = {
"protectAdmin": [true, false, false],
"protectValidator": [false, true, false],
"protectCommercial": [false, false, true],
"noProtectAdmin": [false, true, true],
"noProtectValidator": [true, false, true],
"noProtectCommercial": [true, true, false],
"noProtect": [false, false, false],
"protectAll": [true, true, true],
};
var hasAccess = function(stateName, level) {
var hasAccess = false,
level = level - 1;
if(fields[stateName][level]) {
hasAccess = true;
}
return hasAccess;
};
var checkReadOnlyField = function(fieldName, level) {
return readOnlyFields[fieldName][level - 1];
}
return {
hasAccess: hasAccess,
checkReadOnlyField: checkReadOnlyField
};
};
HTML:
<div class="form-group" level="{{taskCtrl.level}}" check-permissions="noCommercial">
<label for="a_market">
Situación del mercado <span class="highlight">*</span>
</label>
<select id="a_market" name="a_market" class="form-control" ng-change="taskCtrl.setEditTask()"
ng-options="item.id as item.es for item in mainCtrl.market" ng-model="taskCtrl.task.a_id_market"
ng-required="true">
<option value="">N.A.</option>
</select>
<p class="error-message" ng-show="taskForm.a_market.$dirty && taskForm.a_market.$error.required">Campo
Obligatorio</p>
</div>
这里的问题是,当自定义指令删除 div 元素时,表单控件仍然注册到父表单。
一种解决方案是在删除元素时使用 $removeControl(control);
方法注销该控件。 (documentation)
为了实现这一点,首先您需要将父表单引用注入到自定义指令中:
require: '^form',
和控件名称,例如:
scope: {
level: '@',
field: '@'
},
现在在 link 函数中,您可以访问父表单:
link: function(scope, elem, attrs, ctrl) {
console.log('parent form', ctrl);
...
}
您可以注销被删除的控件:
if (!hasPermission) {
elem.remove();
ctrl.$removeControl(ctrl[scope.field]);
}
添加这些元素后,当元素被删除时,表单就可以提交了。
这是一个工作示例:DEMO