#angularjs #angular-directive
#angularjs #angular-директива
Вопрос:
Приведенная ниже директива работает нормально, пока вы не введете ng-required
директиву в дочерний div.
ng-model
Свойство остается обязательным в форме, даже если элемент был удален. В результате пользователь должен заполнить поле, которого нет в форме, прежде чем сможет его отправить.
Текущее решение для исправления, которое мы имеем для этой директивы (которое было сделано кем-то, кто больше не работает в компании), заключается в том, чтобы ввести ng-if
директиву для того же элемента, что и пользовательская директива. Это, очевидно, противоречит цели пользовательской директивы, и теперь, когда мне нужно добавить дополнительные условия, их необходимо исправить.
Я читал другие сообщения и считаю, что проблема связана с областью действия директивы. Тем не менее, я поиграл с параметрами уровня области видимости, а также вышел из области видимости в консоли, чтобы искать метод в стиле уничтожения без какого-либо успеха.
В случае, если реклама видит представление, он, правильно, не увидит html ниже из-за уровня пользователя, равного 3. И все же требование остается…
ПОЛЬЗОВАТЕЛЬСКАЯ ДИРЕКТИВА:
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 amp;amp; taskForm.a_market.$error.required">Campo
Obligatorio</p>
</div>
Ответ №1:
Проблема здесь в том, что, когда пользовательская директива удаляет элемент div, элемент управления формой остается зарегистрированным в родительской форме.
Одним из решений было бы отменить регистрацию этого элемента управления при удалении элемента, используя $removeControl(control);
метод. (документация)
Для этого, прежде всего, вам нужно ввести ссылку на родительскую форму в пользовательскую директиву:
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]);
}
После этих дополнений, когда элемент удаляется, форма становится допустимой для отправки.
Вот рабочий пример: ДЕМОНСТРАЦИЯ
Комментарии:
1. Спасибо Биллу за ваш высоко оцененный ответ. Теперь я понимаю логику происходящего, но все еще не могу удалить ее из элемента управления. В вашем примере форма недействительна при отправке, несмотря на то, что уровень равен 2. Кроме того, вы не передаете поле, как мы делаем с level, и поэтому в моей версии поле все еще не определено…
2. В моем примере, если вы измените уровень на ‘3’, он воспроизводит регистр, и форма становится действительной
3. Я не совсем понимаю ваше последнее предложение, если вы хотите объяснить подробнее
4. Извините, я хотел сказать 3. Когда я меняю уровень на 3, он по-прежнему выдает «недопустимый».
5. Извинения. Я не знаком с jsfiddle.