Wie aktiviere/deaktiviere ich Ankertags mithilfe des Direktive-Ansatzes?
Beispiel:
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);
}
});
}
}
};
});
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:
href
-Links, die beim Klicken nicht zu folgen sindngClick
Ereignisse, die beim Klicken nicht ausgelöst werdendisabled
-KlasseDiese 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;
}
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>
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>
Ä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.
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>
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.
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";
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>
Sie können eine benutzerdefinierte Anweisung erstellen, die der von ng-disabled ähnelt, und eine bestimmte Gruppe von Elementen deaktivieren, indem Sie:
my-disabled
.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;
}
})
}
}
});
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
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>