Включить/отключить привязку с помощью AngularJS
Как включить/отключить теги привязки с помощью директивного подхода?
Пример:
- при нажатии на ссылку редактирования, создание и удаление необходимо отключить или отключить.
- при нажатии на ссылку на создание, редактирование и удаление необходимо отключить или выдать серым цветом
JAVASCRIPT:
angular.module('ngApp', []).controller('ngCtrl',['$scope', function($scope){
$scope.create = function(){
console.log("inside create");
};
$scope.edit = function(){
console.log("inside edit");
};
$scope.delete = function(){
console.log("inside delete");
};
}]).directive('a', function() {
return {
restrict: 'E',
link: function(scope, elem, attrs) {
if(attrs.ngClick || attrs.href === '' || attrs.href === '#'){
elem.on('click', function(e){
e.preventDefault();
if(attrs.ngClick){
scope.$eval(attrs.ngClick);
}
});
}
}
};
});
LINK to CODE
Ответы
Ответ 1
Update:
Отключение href лучше работает при возврате функции ссылки. Код ниже обновлен.
aDisabled
естественно выполняется до ngClick
, потому что директивы сортируются в алфавитном порядке. Когда aDisabled
переименовывается в tagDisabled
, директива работает не.
Чтобы "отключить" тег "a", мне нужны следующие вещи:
-
href
ссылки не будут выполняться при нажатии
-
ngClick
события не срабатывают при нажатии
- стили изменены путем добавления класса
disabled
Эта директива делает это, подражая директиве ngDisabled. Основываясь на значении директивы a-disabled
, все вышеперечисленные функции переключаются.
myApp.directive('aDisabled', function() {
return {
compile: function(tElement, tAttrs, transclude) {
//Disable ngClick
tAttrs["ngClick"] = "!("+tAttrs["aDisabled"]+") && ("+tAttrs["ngClick"]+")";
//return a link function
return function (scope, iElement, iAttrs) {
//Toggle "disabled" to class when aDisabled becomes true
scope.$watch(iAttrs["aDisabled"], function(newValue) {
if (newValue !== undefined) {
iElement.toggleClass("disabled", newValue);
}
});
//Disable href on click
iElement.on("click", function(e) {
if (scope.$eval(iAttrs["aDisabled"])) {
e.preventDefault();
}
});
};
}
};
});
Вот стиль CSS, который может указывать на отключенный тег:
a.disabled {
color: #AAAAAA;
cursor: default;
pointer-events: none;
text-decoration: none;
}
И вот код в действии, с вашим примером
Ответ 2
Моя проблема была несколько иной: у меня есть привязывающие теги, которые определяют href
, и я хочу использовать ng-disabled
, чтобы предотвратить перемещение ссылки нигде при нажатии. Решение состоит в том, чтобы отключить href
, когда ссылка отключена, например:
<a ng-href="{{isDisabled ? '' : '#/foo'}}"
ng-disabled="isDisabled">Foo</a>
В этом случае ng-disabled
используется только для стилизации элемента.
Если вы хотите избежать с использованием неофициальных атрибутов, вам нужно будет самостоятельно стилизовать его:
<style>
a.disabled {
color: #888;
}
</style>
<a ng-href="{{isDisabled ? '' : '#/foo'}}"
ng-class="{disabled: isDisabled}">Foo</a>
Ответ 3
Для людей, которые не хотят сложного ответа, я использовал Ng-If, чтобы решить это для чего-то подобного:
<div style="text-align: center;">
<a ng-if="ctrl.something != null" href="#" ng-click="ctrl.anchorClicked();">I'm An Anchor</a>
<span ng-if="ctrl.something == null">I'm just text</span>
</div>
Ответ 4
Изменить @Nitin ответ для работы с динамическим отключением:
angular.module('myApp').directive('a', function() {
return {
restrict: 'E',
link: function(scope, elem, attrs) {
elem.on('click', function(e) {
if (attrs.disabled) {
e.preventDefault(); // prevent link click
}
});
}
};
});
Это проверяет наличие отключенного атрибута и его значение при каждом нажатии.
Ответ 5
Отказ от ответственности:
ОП высказал этот комментарий еще на один ответ:
Мы можем иметь ngDisabled для кнопок или тегов ввода; используя CSS, мы можем чтобы кнопка выглядела как тег привязки, но это мало помогает! я был более заинтересован в том, как это можно сделать с помощью директивного подхода или angular способ сделать это?
Вы можете использовать переменную внутри области вашего контроллера, чтобы отключить ссылки/кнопки в соответствии с последней кнопкой/ссылкой, на которую вы нажали, с помощью ng-click
, чтобы установить переменную с правильным значением и ng-disabled
для отключения кнопки при необходимости в соответствии со значением в переменной.
Я обновил ваш Plunker, чтобы дать вам представление.
Но в основном, это что-то вроде этого:
<div>
<button ng-click="create()" ng-disabled="state === 'edit'">CREATE</button><br/>
<button ng-click="edit()" ng-disabled="state === 'create'">EDIT</button><br/>
<button href="" ng-click="delete()" ng-disabled="state === 'create' || state === 'edit'">DELETE</button>
</div>
Ответ 6
Вы пытались использовать ленивую оценку выражений типа disabled || someAction()
?
Предположим, что я определил что-то вроде этого в контроллере:
$scope.disabled = true;
Затем я могу отключить ссылку и применить встроенные стили следующим образом:
<a data-ng-click="disabled || (GoTo('#/employer/'))" data-ng-style="disabled && { 'background-color': 'rgba(99, 99, 99, 0.5)', }">Higher Level</a>
Или еще лучше отключить ссылку и применить класс следующим образом:
<a data-ng-click="disabled || (GoTo('#/employer/'))" data-ng-class="{ disabled: disabled }">Higher Level</a>
Примечание: у вас будет class="disabled"
, примененный к элементу DOM этим оператором.
На этом этапе вам просто нужно обработать то, что вы делаете GoTo()
. В моем случае это так же просто, как перенаправление на связанное состояние:
$scope.GoTo = function (state) {
if (state != undefined && state.length > 0) {
$window.location.hash = state;
}
};
Вместо ограничения ngDisabled
вы ограничены тем, что вы решите сделать.
С помощью этой техники я успешно применил проверку уровня разрешений для включения или отключения доступа пользователя к определенной части моего модуля.
Простой плункер, чтобы продемонстрировать точку
Ответ 7
Вы можете создать настраиваемую директиву, которая каким-то образом похожа на ng-disabled и отключить определенный набор элементов:
- просмотр изменений свойств настраиваемой директивы, например.
my-disabled
.
- клонировать текущий элемент без добавления обработчиков событий.
- добавить свойства css к клонированному элементу и другим атрибутам или обработчикам событий, которые будут
предоставить отключенное состояние элемента.
- когда изменения обнаружены в наблюдаемом свойстве, замените текущий элемент клонированным элементом.
HTML
<a my-disabled="disableCreate" href="#" ng-click="disableEdit = true">CREATE</a><br/>
<a my-disabled="disableEdit" href="#" ng-click="disableCreate = true">EDIT</a><br/>
<a my-disabled="disableCreate || disableEdit" href="#">DELETE</a><br/>
<a href="#" ng-click="disableEdit = false; disableCreate = false;">RESET</a>
JAVASCRIPT
directive('myDisabled', function() {
return {
link: function(scope, elem, attr) {
var color = elem.css('color'),
textDecoration = elem.css('text-decoration'),
cursor = elem.css('cursor'),
// double negation for non-boolean attributes e.g. undefined
currentValue = !!scope.$eval(attr.myDisabled),
current = elem[0],
next = elem[0].cloneNode(true);
var nextElem = angular.element(next);
nextElem.on('click', function(e) {
e.preventDefault();
e.stopPropagation();
});
nextElem.css('color', 'gray');
nextElem.css('text-decoration', 'line-through');
nextElem.css('cursor', 'not-allowed');
nextElem.attr('tabindex', -1);
scope.$watch(attr.myDisabled, function(value) {
// double negation for non-boolean attributes e.g. undefined
value = !!value;
if(currentValue != value) {
currentValue = value;
current.parentNode.replaceChild(next, current);
var temp = current;
current = next;
next = temp;
}
})
}
}
});
Ответ 8
Сделайте функцию переключения в соответствующей области серой ссылке.
Сначала создайте следующие CSS-классы в вашем файле .css.
.disabled {
pointer-events: none;
cursor: default;
}
.enabled {
pointer-events: visible;
cursor: auto;
}
Добавьте переменную $scope.state и $scope.toggle. Отредактируйте свой контроллер в файле JS, например:
$scope.state='on';
$scope.toggle='enabled';
$scope.changeState = function () {
$scope.state = $scope.state === 'on' ? 'off' : 'on';
$scope.toggleEdit();
};
$scope.toggleEdit = function () {
if ($scope.state === 'on')
$scope.toggle = 'enabled';
else
$scope.toggle = 'disabled';
};
Теперь в HTML теги редактируются как:
<a href="#" ng-click="create()" class="{{toggle}}">CREATE</a><br/>
<a href="#" ng-click="edit()" class="{{toggle}}">EDIT</a><br/>
<a href="#" ng-click="delete()" class="{{toggle}}">DELETE</a>
Чтобы избежать проблемы с отключением канала,
измените класс DOM CSS в конце функции.
document.getElementById("create").className = "enabled";
Ответ 9
Вы можете переопределить тег a
, используя директиву angular:
angular.module('myApp').directive('a', function() {
return {
restrict: 'E',
link: function(scope, elem, attrs) {
if ('disabled' in attrs) {
elem.on('click', function(e) {
e.preventDefault(); // prevent link click
});
}
}
};
});
В html:
<a href="nextPage" disabled>Next</a>
Ответ 10
Я ожидаю, что привязанные теги приведут к статической странице с URL-адресом. Я думаю, что кнопки больше подходят для вашего прецедента, а затем вы можете использовать ngDisabled для его отключения. Из документов: https://docs.angularjs.org/api/ng/directive/ngDisabled