Подтвердить что ты не робот

Включить/отключить привязку с помощью 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

4b9b3361

Ответ 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