Angular2, wie kann man ein Ankerelement richtig deaktivieren?

73

Ich arbeite an einer Angular2- Anwendung und muss anzeigen - aber disableein <a> HTML- Element. Was ist der richtige Weg, um dies zu tun?

Aktualisiert

Bitte beachten Sie *ngFor, dass dies die Option verhindern würde, das Ganze zu verwenden *ngIfund nicht zu rendern <a>.

<a *ngFor="let link of links"
   href="#" 
   [class.disabled]="isDisabled(link)" 
   (click)="onClick(link)">
   {{ link.name }}
</a>

Die TypeScript- Komponente verfügt über eine Methode, die folgendermaßen aussieht:

onClick(link: LinkObj) {
    // Do something relevant with the object... 
    return false;
}

Ich muss tatsächlich verhindern, dass das Element anklickbar ist, und nicht nur den Eindruck erwecken, dass es sich um das CSS handelt . Ich ging davon aus, dass ich zuerst möglicherweise an das [disabled]Attribut binden musste , aber dies ist falsch, da das Ankerelement keine disabledEigenschaft hat.

Ich habe mir das angeschaut und darüber nachgedacht, es zu verwenden, pointer-events: noneaber dies verhindert, dass mein cursor: not-allowedArbeitsstil funktioniert - und dies ist Teil der Anforderung.

David Pine
quelle

Antworten:

103

Wenn Sie pointer-events: nonein CSS angeben, wird die Mauseingabe deaktiviert, die Tastatureingabe jedoch nicht. Beispielsweise kann der Benutzer weiterhin auf den Link klicken und ihn durch Drücken der EnterTaste oder (unter Windows) der ≣ MenuTaste "anklicken" . Sie könnten bestimmte Tastenanschläge deaktivieren, indem Sie das keydownEreignis abfangen. Dies würde jedoch wahrscheinlich Benutzer verwirren, die sich auf unterstützende Technologien verlassen.

Der wahrscheinlich beste Weg, einen Link zu deaktivieren, besteht darin, sein hrefAttribut zu entfernen und ihn zu einem Nicht-Link zu machen. Sie können dies dynamisch mit einer bedingten hrefAttributbindung tun :

<a *ngFor="let link of links"
   [attr.href]="isDisabled(link) ? null : '#'"
   [class.disabled]="isDisabled(link)"
   (click)="!isDisabled(link) && onClick(link)">
   {{ link.name }}
</a>

Oder, wie in der Antwort von Günter Zöchbauer, können Sie zwei Links erstellen, einen normalen und einen deaktivierten, und verwenden *ngIf, um den einen oder anderen anzuzeigen:

<ng-template ngFor #link [ngForOf]="links">
    <a *ngIf="!isDisabled(link)" href="#" (click)="onClick(link)">{{ link.name }}</a>
    <a *ngIf="isDisabled(link)" class="disabled">{{ link.name }}</a>
</ng-template>

Hier ist etwas CSS, damit der Link deaktiviert aussieht:

a.disabled {
    color: gray;
    cursor: not-allowed;
    text-decoration: underline;
}
Michael Liu
quelle
1
Selbst wenn das <a>Element fehlt und hrefes immer noch anklickbar ist, habe ich dies gerade überprüft ... was jetzt? Immer noch nicht perfekt.
David Pine
1
@DavidPine: Ich habe meine Antwort aktualisiert, um das clickEreignis zu behandeln .
Michael Liu
Der große Nachteil Sie die SEO auf diesen Prozess verlieren, haben Sie einen Blick: webmasters.stackexchange.com/questions/74032/...
jcdsr
Sie können auch [attr.disabled]="isDisabled(link)"im <a> -Tag verwenden.
Sri
2
@Sriram: Do not verwenden [attr.disabled]auf einem <a>Etikett. Es ist nicht standardkonform und funktioniert nur in Internet Explorer, nicht in Chrome oder Firefox.
Michael Liu
37

Für [routerLink]Sie können verwenden:

Das Hinzufügen dieses CSS sollte das tun, was Sie wollen:

a.disabled {
   pointer-events: none;
   cursor: not-allowed; 
}

Dies sollte das von @MichelLiu in den Kommentaren erwähnte Problem beheben:

<a href="#" [class.disabled]="isDisabled(link)"
    (keydown.enter)="!isDisabled(link)">{{ link.name }}</a>

Ein anderer Ansatz

<a [routerLink]="['Other']" *ngIf="!isDisabled(link)">{{ link.name }}</a>
<a  *ngIf="isDisabled(link)">{{ link.name }}</a>  

Plunker Beispiel

Günter Zöchbauer
quelle
Also würde ich mich nicht binden wollen [disabled], warum nicht?
David Pine
1
Der Benutzer kann weiterhin auf den Link tippen und die Eingabetaste drücken.
Michael Liu
@ MichaelLiu interessant Also würde es auch erfordern(focus)="isDisabled(link) ? false : true"
Günter Zöchbauer
2
@ GünterZöchbauer Jede Winkelfrage, nach der ich bei SO gesucht habe, hast du beantwortet! Gute Arbeit!
JMK
2
@ JMK danke: D Es hat Spaß gemacht. Leider nicht mehr so ​​viel Zeit.
Günter Zöchbauer
5

Ich bin gerade auf diese Frage gestoßen und wollte einen alternativen Ansatz vorschlagen.

In dem vom OP bereitgestellten Markup gibt es eine Klickereignisbindung. Dies lässt mich denken, dass die Elemente als "Schaltflächen" verwendet werden. Wenn dies der Fall ist, können sie als <button>Elemente markiert und wie Links gestaltet werden, wenn dies der gewünschte Look ist. (Bootstrap verfügt beispielsweise über einen integrierten "Link" -Schaltflächenstil. https://v4-alpha.getbootstrap.com/components/buttons/#examples) ).)

Dies hat mehrere direkte und indirekte Vorteile. Es ermöglicht Ihnen, sich an die zu bindendisabled Eigenschaft herstellen, die beim Festlegen Maus- und Tastaturereignisse automatisch deaktiviert. Sie können den deaktivierten Status basierend auf dem deaktivierten Attribut formatieren, sodass Sie nicht auch die Klasse des Elements bearbeiten müssen. Es ist auch besser für die Zugänglichkeit.

Eine ausführliche Beschreibung der Verwendung von Schaltflächen und der Verwendung von Links finden Sie unter Links sind keine Schaltflächen. Weder sind DIVs noch SPANs

Van J. Wilson
quelle
5

Meine Antwort könnte für diesen Beitrag zu spät sein. Dies kann nur durch Inline-CSS innerhalb des Ankertags erreicht werden.

<a [routerLink]="['/user']" [style.pointer-events]="isDisabled ?'none':'auto'">click-label</a>

Berücksichtigt isDisabledwird eine Eigenschaft in einer Komponente, die trueoder sein kann false.

Plunker dafür: https://embed.plnkr.co/TOh8LM/

Vineetk27
quelle
Ich glaube nicht, dass das richtig ist. Angular verbreitet immer noch die (Klick-) Bindung, als solche würde sie immer noch auftreten. Bitte erstellen Sie damit einen Plunker und teilen Sie ihn hier.
David Pine
@ DavidPine Ich füge einen Plunker dafür hinzu. embedded.plnkr.co/TOh8LM Ich habe gerade eine Referenz für das href-Tag angegeben, ähnlich wie es mit der routerLinkDirektive innerhalb des
Ankertags
3
   .disabled{ pointer-events: none }

deaktiviert das Klickereignis, jedoch nicht das Registerkartenereignis. Um das Tab-Ereignis zu deaktivieren, können Sie den Tabindex auf -1 setzen, wenn das Deaktivierungsflag wahr ist.

<li [routerLinkActive]="['active']" [class.disabled]="isDisabled">
     <a [routerLink]="['link']" tabindex="{{isDisabled?-1:0}}" > Menu Item</a>
</li>
Darin Cardin
quelle
2

Betrachten Sie die folgende Lösung

.disable-anchor-tag { 
  pointer-events: none; 
}
Sahil Ralkar
quelle
1

Dies gilt für Ankertags, die als Registerkarten dienen:

[ngStyle]="{'pointer-events': isSaving ? 'none': 'auto'}"
Henry
quelle
0

Ich habe benutzt

tabindex="{{isEditedParaOrder?-1:0}}" 
[style.pointer-events]="isEditedParaOrder ?'none':'auto'" 

In meinem Ankertag, damit sie nicht zum Ankertag wechseln können, indem sie die Tabulatortaste verwenden, um die Eingabetaste und auch den Zeiger selbst zu verwenden, setzen wir basierend auf der Eigenschaft 'isEditedParaO rder' whi 'none'

Gast
quelle
-2

Sie können dies versuchen

<a [attr.disabled]="someCondition ? true: null"></a>
Vincent Shen
quelle
-2

Benutz einfach

<a [ngClass]="{'disabled': your_condition}"> This a tag is disabled</a>

Beispiel:

 <a [ngClass]="{'disabled': name=='junaid'}"> This a tag is disabled</a>
Pullat Junaid
quelle
Dies funktioniert nicht, obwohl es so aussieht, als wäre es deaktiviert - es ist tatsächlich immer noch anklickbar und löst das Problem überhaupt nicht.
David Pine
Hier ist die richtige Antwort ... stackoverflow.com/a/36987506/2410379
David Pine