Wie füge ich ein bedingtes Attribut in Angular 2 hinzu?

276

Wie kann ich bedingt ein Elementattribut hinzufügen, z. B. das checkedeines Kontrollkästchens?

Frühere Versionen von Angular hatten NgAttrund ich denke NgChecked, alle scheinen die Funktionalität zu bieten, nach der ich suche. Diese Attribute scheinen jedoch in Angular 2 nicht vorhanden zu sein, und ich sehe keine andere Möglichkeit, diese Funktionalität bereitzustellen.

Jonathan Miles
quelle
Siehe auch: stackoverflow.com/questions/42179150/…
Aloisdg wechselt zu codidact.com
2
Googler, falls Sie ein wertloses Attribut für eine Winkelkomponente wünschen, siehe hier
Frank Nocke

Antworten:

574

null entfernt es:

[attr.checked]="value ? '' : null"

oder

[attr.checked]="value ? 'checked' : null"

Hinweis:

Attribut gegen Eigenschaft

Wenn das HTML-Element, in das Sie diese Bindung einfügen, keine Eigenschaft mit dem in der Bindung verwendeten Namen hat ( checkedin diesem Fall) und auch keine Winkelkomponente oder -anweisung auf dasselbe Element angewendet wird, das eine hat @Input() checked;, [xxx]="..."kann es nicht verwendet werden.

Siehe auch Was ist der Unterschied zwischen Eigenschaften und Attributen in HTML?

Woran zu binden ist, wenn es keine solche Eigenschaft gibt

Alternativen sind [style.xxx]="...", [attr.xxx]="...", [class.xxx]="..."je nachdem , was Sie versuchen zu erreichen.

Denn <input>nur ein checkedAttribut, aber keine checkedEigenschaft [attr.checked]="..."ist der richtige Weg für diesen speziellen Fall.

Attribute können nur Zeichenfolgenwerte verarbeiten

Eine häufige Gefahr besteht auch darin, dass für [attr.xxx]="..."Bindungen der Wert ( ...) immer stringifiziert ist. Nur Eigenschaften und @Input()s können andere Werttypen wie Boolesche Werte, Zahlen, Objekte, ... empfangen.

Die meisten Eigenschaften und Attribute von Elementen sind miteinander verbunden und haben denselben Namen.

Eigenschaftsattributverbindung

Wenn die Eigenschaft an das Attribut gebunden ist, erhält sie auch nur den String-Wert vom Attribut.
Wenn die Eigenschaft an die Eigenschaft gebunden ist, erhält sie den daran gebundenen Wert (Boolescher Wert, Zahl, Objekt, ...) und das Attribut erneut den Zeichenwert.

Zwei Fälle, in denen Attribut- und Eigenschaftsnamen nicht übereinstimmen.

Angular wurde seitdem geändert und kennt diese Sonderfälle und behandelt sie so, dass Sie sie binden können, <label [for]="obwohl keine solche Eigenschaft vorhanden ist (dasselbe gilt für colspan).

Günter Zöchbauer
quelle
3
Sie können das "attr" weglassen. Präfix.
Filip Stachowiak
16
@FilipStachowiak dann wird es kein Attribut. Es gibt verschiedene Eigenschaften für viele Elemente, bei denen das Element selbst den Wert widerspiegelt, der an eine Eigenschaft eines Attributs gebunden ist (und auch die andere Richtung). In diesem Fall brauchen Sie nicht attr.. Wenn Sie jedoch ein benutzerdefiniertes Attribut hinzufügen möchten, benötigen Sie auf jeden Fall das attr.Präfix
Günter Zöchbauer
14
Um klar zu sein, brauchen Sie den attr.Teil davon. Ich habe versucht festzulegen [href]und wollte nur, dass es festgelegt wird, wenn die hrefEigenschaft des Elements vorhanden ist. Ohne [attr.href]dies würde eine href mit dem Wert 'null' hinzugefügt, die beim Klicken die aktuelle Seite aktualisiert. [attr.href]behoben.
Dudewad
@dudewad das klingt für mich nicht richtig. Wenn Sie hrefein Element mit der hrefEigenschaft festlegen , müssen Sie es nicht verwenden attr. Es muss noch etwas schief gehen.
Günter Zöchbauer
@ günter-zöchbauer Nun, ich verwende Ng 4.x, und <a [href]="item.href">wo item.hrefundefiniert ist (nicht der Wert undefiniert, aber die Eigenschaft hrefexistiert nicht auf item) wurde das hrefAttribut auf gesetzt null. Ich habe mich nicht mit der Quelle befasst, weil es mich an dieser Stelle ehrlich gesagt nicht sonderlich interessiert (dies ist ein winziges Detail), aber es attr.handelt sich um eine völlig andere Richtlinie, und daher ist es für mich keine Überraschung, dass ich mich anders verhalte.
Dudewad
37

in Winkel-2 Attribut Syntax ist

<div [attr.role]="myAriaRole">

Bindet dem Ergebnis des Ausdrucks myAriaRole eine Attributrolle.

so kann man gerne benutzen

[attr.role]="myAriaRole ? true: null"
Shaishab Roy
quelle
9
Das Problem hierbei ist , dass , wenn your expressionist falsedas Attribut in dem DOM aussehen wird <div checked="false">. Ich denke nicht, dass dies der beabsichtigte Effekt ist.
Günter Zöchbauer
7
Danke, aber ich habe gefragt, wie man das Attribut bedingt hinzufügt und seinen Wert nicht bedingt zuweist.
Jonathan Miles
Sie können sogar das "attr" weglassen. Präfix.
Filip Stachowiak
1
@FilipStachowiak dann wird es kein Attribut. Es gibt verschiedene Eigenschaften für viele Elemente, bei denen das Element selbst den Wert widerspiegelt, der an eine Eigenschaft eines Attributs gebunden ist (und auch die andere Richtung). In diesem Fall brauchen Sie nicht attr.. Wenn Sie jedoch ein benutzerdefiniertes Attribut hinzufügen möchten, benötigen Sie auf jeden Fall das attr.Präfix
Günter Zöchbauer
oh man, das: null ist erstaunlich, die Sache wusste, dass dies unter bestimmten Bedingungen verwendet werden kann! Danke für die Lösung.
Pinarella
17

Verfeinerung Günter Zöchbauer Antwort:

Dies scheint jetzt anders zu sein. Ich habe versucht, dies zu tun, um ein href-Attribut bedingt auf ein Ankertag anzuwenden. Sie müssen undefined für den Fall "Nicht anwenden" verwenden. Als Beispiel werde ich anhand eines Links demonstrieren, bei dem ein href-Attribut bedingt angewendet wird.

Ein Ankertag ohne href-Attribut wird zu einfachem Text, der einen Platzhalter für einen Link gemäß der Hyperlink-Spezifikation angibt .

Für meine Navigation habe ich eine Liste von Links, aber einer dieser Links repräsentiert die aktuelle Seite. Ich wollte nicht, dass der aktuelle Seitenlink ein Link ist, möchte aber dennoch, dass er in der Liste angezeigt wird (er hat einige benutzerdefinierte Stile, aber dieses Beispiel ist vereinfacht).

<a [attr.href]="currentUrl !== link.url ? link.url : undefined">

Dies ist sauberer als die Verwendung von zwei * ngIf auf einem Span- und Anker-Tag, denke ich.

Ragnaraxis
quelle
4

Wenn es sich um ein Eingabeelement handelt, können Sie so etwas wie ... schreiben. <input type="radio" [checked]="condition">Der Wert der Bedingung muss wahr oder falsch sein.

Auch für Stilattribute ... <h4 [style.color]="'red'">Some text</h4>

Rohit Tirmanwar
quelle
4

Sie können dies verwenden.

<span [attr.checked]="val? true : false"> </span>

WapShivam
quelle
Sie haben Ihren Attributwert mit 'val' überprüft. Wenn es wahr wird, gibt einfach wahr zurück, andernfalls gibt es einen falschen Wert zurück
WapShivam
1

Sie können einen besseren Ansatz für jemanden verwenden, der HTML für ein bereits vorhandenes scss schreibt.
html

[attr.role]="<boolean>"

scss

[role = "true"] { ... }

Auf diese Weise müssen Sie nicht <boolean> ? true : nulljedes Mal.

João Ghignatti
quelle
Das funktioniert nicht in jedem Fall. Zum Beispiel funktioniert es nicht mit multipleAttributen für selectElemente.
Smartmouse
0

Hier wird der Absatz nur gedruckt. 'IsValid' ist true / enthält einen beliebigen Wert

<p *ngIf="isValid ? true : false">Paragraph</p>
Aishwarya Kathavarayan
quelle
0

Ich wollte einen Tooltip nur für ein bestimmtes Feld haben, wie unten im Code hinzugefügt, aber Sie möchten einen Tooltip für Multiplikatoren haben. Sie können ein Array-Valdidat verwenden, indem Sie:

Mehrere Elemente mit benutzerdefiniertem Daten-Tooltip- Attribut:

1: [ 'key1ToHaveTooltip', `key2ToHaveTooltip ']. Includes (key)

2: ['key1ToHaveTooltip', 'key2ToHaveTooltip']. IndexOf (key)> -1

Tooltip-Attribut für mehr als 1 Element haben.

   <div *ngFor="let key of Keys"
             [attr.data-tooltip]="key === 'IwantOnlyThisKeyToHaveTooltipAttribute' 
                                           ? 'Hey! I am a tooltip on key matched'
                                           : null">
   </div>
Khizer
quelle
-7

Auch Inline-Maps sind praktisch.

Sie sind auch etwas expliziter und lesbarer.

[class]="{ 'true': 'active', 'false': 'inactive', 'true&false': 'some-other-class' }[ trinaryBoolean ]"

Nur eine andere Möglichkeit, dasselbe zu erreichen, falls Ihnen die ternäre Syntax oder ngIfs (usw.) nicht gefällt .

Cody
quelle
1
Eine Klasse ist etwas ganz anderes als ein Attribut (worum es in der Frage geht)
Günter Zöchbauer
1
Sie könnten sich auch die Mühe machen, die Frage richtig zu beantworten, dann hatte ich einen Grund, meine Abstimmung zu überdenken, und ich hätte auch ohne Kommentar abstimmen können, um Sie im Dunkeln darüber zu halten, wofür die Ablehnung war.
Günter Zöchbauer
1
@Cody können Sie erklären (Beispielcode angeben), wie Ihre Methode mit checkedAttributen (Hinzufügen / Entfernen zum Eingabe-Tag) in funktioniert <input type="checkbox" name="vehicle" value="Car" checked>? (Wenn wir in Ihrem Code ändern class, checkboxfunktioniert es NICHT (ich überprüfe dies))
Kamil Kiełczewski