wake-up-neo.com

Ankertags mit AngularJS aktivieren/deaktivieren

Wie aktiviere/deaktiviere ich Ankertags mithilfe des Direktive-Ansatzes? 

Beispiel: 

  1. wenn Sie auf den Link Bearbeiten klicken, muss Erstellen & Löschen deaktiviert oder ausgegraut sein
  2. wenn Sie auf Link erstellen klicken, muss Bearbeiten & Löschen deaktiviert oder ausgegraut sein

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 zu CODE

52
John Smith

Update: Das Deaktivieren von href funktioniert besser im Link-Funktionsrücksprung. Code unten wurde aktualisiert.

aDisabled wird natürlich vor ngClick ausgeführt, da Anweisungen in alphabetischer Reihenfolge sortiert werden. Wenn aDisabled in tagDisabled umbenannt wird, funktioniert die Direktive not nicht.


Um das "a" -Tag zu "deaktivieren", möchte ich folgende Dinge:

  1. href-Links, die beim Klicken nicht zu folgen sind
  2. ngClick Ereignisse, die beim Klicken nicht ausgelöst werden
  3. stile geändert durch Hinzufügen einer disabled-Klasse

Diese Direktive tut dies, indem sie die Direktive ngDisabled nachahmt. Basierend auf dem Wert der Direktive a-disabled werden alle oben genannten Funktionen umgeschaltet.

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();
                    }
                });
            };
        }
    };
});

Hier ist ein CSS-Stil, der auf ein deaktiviertes Tag hinweisen könnte:

a.disabled {
    color: #AAAAAA;
    cursor: default;
    pointer-events: none;
    text-decoration: none;
}

Und hier ist der Code in Aktion, mit deinem Beispiel

54
Wasmoo

Mein Problem war etwas anders: Ich habe Ankertags, die eine href definieren, und ich möchte ng-disabled verwenden, um zu verhindern, dass der Link beim Klicken an eine beliebige Stelle verschoben wird. Die Lösung besteht darin, die Variable href zu deaktivieren, wenn die Verknüpfung deaktiviert ist, wie folgt:

<a ng-href="{{isDisabled ? '' : '#/foo'}}"
   ng-disabled="isDisabled">Foo</a>

In diesem Fall wird ng-disabled nur zur Gestaltung des Elements verwendet.

Wenn Sie mit inoffiziellen Attributen vermeiden möchten, müssen Sie es selbst gestalten:

<style>
a.disabled {
    color: #888;
}
</style>
<a ng-href="{{isDisabled ? '' : '#/foo'}}"
   ng-class="{disabled: isDisabled}">Foo</a>
23
z0r

Für Leute, die keine komplizierte Antwort wünschen, habe ich Ng-If verwendet, um dies für etwas Ähnliches zu lösen:

<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>
9
Capt. Rochefort

Ändern von @ Nitin's answer , um mit dynamischer Deaktivierung zu arbeiten:

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
        }
      });
    }
  };
});

Dadurch wird das Vorhandensein des deaktivierten Attributs und der Wert bei jedem Klick überprüft.

6
jsruok

Haftungsausschluss:

Das OP hat diesen Kommentar zu einer anderen Antwort abgegeben:

Wir können ngDisabled für Buttons oder Input-Tags haben. mit CSS können wir machen Sie den Button wie ein Anker-Tag, aber das hilft nicht viel! ICH war mehr daran interessiert, zu sehen, wie dies mit dem Direktiven Ansatz geschehen kann. oder eckig?


Sie können eine Variable innerhalb des Bereichs Ihres Controllers verwenden, um die Verknüpfungen/Schaltflächen entsprechend der letzten angeklickten Schaltfläche/Verknüpfung zu deaktivieren, indem Sie mit ng-click die Variable auf den korrekten Wert setzen und mit ng-disabled die Schaltfläche bei Bedarf deaktivieren auf den Wert in der Variablen.

Ich habe Ihren Plunker aktualisiert, um Ihnen eine Idee zu geben.

Aber im Grunde ist es so etwas:

 <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>
4
Julien

Haben Sie es mit einer faulen Auswertung von Ausdrücken wie disabled || someAction() versucht?

Nehmen wir an, ich habe in meinem Controller so etwas definiert:

$scope.disabled = true;

Dann kann ich einen Link deaktivieren und Inline-Stile wie folgt anwenden:

<a data-ng-click="disabled || (GoTo('#/employer/'))" data-ng-style="disabled && { 'background-color': 'rgba(99, 99, 99, 0.5)', }">Higher Level</a>

Oder besser noch einen Link deaktivieren und eine Klasse wie folgt anwenden:

<a data-ng-click="disabled || (GoTo('#/employer/'))" data-ng-class="{ disabled: disabled }">Higher Level</a>

Hinweis: Mit dieser Anweisung wird ein class="disabled" auf das DOM-Element angewendet.

In diesem Stadium müssen Sie nur noch mit der Aktion GoTo() umgehen. In meinem Fall ist es so einfach wie die Weiterleitung in den zugehörigen Zustand:

$scope.GoTo = function (state) {
    if (state != undefined && state.length > 0) {
        $window.location.hash = state;
    }
};

Anstatt durch ngDisabled begrenzt zu sein, sind Sie durch das, was Sie tun möchten, eingeschränkt.

Mit dieser Technik wurde die Berechtigungsprüfung erfolgreich angewendet, um den Benutzerzugriff auf bestimmte Teile meines Moduls zu aktivieren oder zu deaktivieren.

Einfacher Plunker, um den Punkt zu demonstrieren

3
iiminov

Machen Sie eine Toggle-Funktion im jeweiligen Bereich, um den Link auszublenden .

Erstellen Sie zunächst die folgenden CSS-Klassen in Ihrer .css-Datei.

.disabled {
    pointer-events: none;
    cursor: default;
}

.enabled {
    pointer-events: visible;
    cursor: auto;
}

Fügen Sie eine Variable $ scope.state und $ scope.toggle hinzu. Bearbeiten Sie Ihren Controller in der JS-Datei wie folgt:

    $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';
        };

Jetzt im HTML-Format bearbeiten sich Tags als:

<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>

Ändern Sie die DOM-CSS-Klasse am Ende der Funktion, um zu vermeiden, dass der Link sich selbst deaktiviert.

document.getElementById("create").className = "enabled";
1
Rohan Gada

Sie können das Tag a mithilfe der Winkelanweisung neu definieren:

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
        });
      }
    }
  };
});

In HTML:

<a href="nextPage" disabled>Next</a>
1
Nitin...

Sie können eine benutzerdefinierte Anweisung erstellen, die der von ng-disabled ähnelt, und eine bestimmte Gruppe von Elementen deaktivieren, indem Sie:

  1. die Eigenschaftsänderungen der benutzerdefinierten Direktive beobachten, z. my-disabled.
  2. klonen Sie das aktuelle Element ohne die hinzugefügten Ereignishandler.
  3. fügen Sie dem geklonten Element css-Eigenschaften und andere Attribute oder Ereignishandler hinzu, die den deaktivierten Status eines Elements angeben.
  4. wenn Änderungen an der überwachten Eigenschaft festgestellt werden, ersetzen Sie das aktuelle Element durch das geklonte Element.

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;
        }

      })
    }
  }
});
1
ryeballar

Ich würde erwarten, dass Ankertags zu einer statischen Seite mit einer URL führen. Ich denke, dass ein Button mehr zu Ihrem Anwendungsfall passt, und dann können Sie ihn mit ngDisabled deaktivieren. Aus den Dokumenten: https://docs.angularjs.org/api/ng/directive/ngDisabled

0
haimlit

ui-router v1.0.18 führt die Unterstützung für ng-disabled für Ankertags ein

Beispiel: <a ui-sref="go" ng-disabled="true">nogo</a>

0
delta711