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