web-dev-qa-db-fra.com

Quel est le meilleur moyen d'appliquer conditionnellement les attributs dans AngularJS?

Je dois pouvoir ajouter, par exemple, "contenteditable" aux éléments, en fonction d'une variable booléenne de portée.

Exemple d'utilisation:

<h1 attrs="{'contenteditable=\"true\"': editMode}">{{content.title}}</h1>

Contenteditable = true serait ajouté à l'élément si $scope.editMode était défini sur true. Existe-t-il un moyen simple d'implémenter ce comportement d'attribut de type ng-class? J'envisage d'écrire une directive et de partager sinon.

Edit: Je vois qu'il semble y avoir quelques similitudes entre ma directive attrs proposée et ng-bind-attrs, mais elle a été supprimée dans 1.0.0.rc3 ?

269
Kenneth Lynne

J'utilise les éléments suivants pour définir de manière conditionnelle la classe attr lorsque la classe ng ne peut pas être utilisée (par exemple, lors du style SVG):

ng-attr-class="{{someBoolean && 'class-when-true' || 'class-when-false' }}"

La même approche devrait fonctionner pour d'autres types d'attributs.

(Je pense que vous devez être sur la dernière angulaire instable pour utiliser ng-attr-, je suis actuellement sur la 1.1.4)

258
Ashley Davis

Vous pouvez préfixer les attributs avec ng-attr pour évaluer une expression angulaire. Lorsque le résultat des expressions non définies, cela supprime la valeur de l'attribut.

<a ng-attr-href="{{value || undefined}}">Hello World</a>

Produira (lorsque la valeur est fausse)

<a ng-attr-href="{{value || undefined}}" href>Hello World</a>

Donc, n'utilisez pas false car cela produira le mot "faux" comme valeur.

<a ng-attr-href="{{value || false}}" href="false">Hello World</a>

Lors de l'utilisation de cette astuce dans une directive. Les attributs de la directive seront faux s'il leur manque une valeur.

Par exemple, ce qui précède serait faux.

function post($scope, $el, $attr) {
      var url = $attr['href'] || false;
      alert(url === false);
}
111
cgTag

Je travaille avec un réglage difficile de l'attribut. Et contrôler l'applicabilité de l'attribut à l'aide de la valeur booléenne de l'attribut.

Voici l'extrait de code:

<div contenteditable="{{ condition ? 'true' : 'false'}}"></div>

J'espère que ça aide.

92
jsbisht

Dans la dernière version de Angular (1.1.5), ils ont inclus une directive conditionnelle appelée ngIf. Il diffère de ngShow et ngHide en ce que les éléments ne sont pas cachés, mais pas inclus dans le DOM. Ils sont très utiles pour les composants coûteux à créer mais non utilisés:

<h1 ng-if="editMode" contenteditable=true>{{content.title}}</h1>
21
Brian Genisio

Pour obtenir un attribut indiquant une valeur spécifique basée sur une vérification booléenne ou omis entièrement si la vérification booléenne échoue, j'ai utilisé les éléments suivants:

ng-attr-example="{{params.type == 'test' ? 'itWasTest' : undefined }}"

Exemple d'utilisation:

<div ng-attr-class="{{params.type == 'test' ? 'itWasTest' : undefined }}">

Afficherait <div class="itWasTest"> ou <div> en fonction de la valeur de params.type

13
Glen

<h1 ng-attr-contenteditable="{{isTrue || undefined }}">{{content.title}}</h1>

produira quand isTrue = true: <h1 contenteditable="true">{{content.title}}</h1>

et quand isTrue = false: <h1>{{content.title}}</h1>

9
Garfi

En ce qui concerne la solution acceptée, celle publiée par Ashley Davis, la méthode décrite imprime toujours l'attribut dans le DOM, indépendamment du fait que la valeur qui lui a été attribuée est indéfinie.

Par exemple, dans une configuration de champ de saisie avec un attribut ng-model et un attribut value:

<input type="text" name="myInput" data-ng-attr-value="{{myValue}}" data-ng-model="myModel" />

Indépendamment de ce qui se cache derrière myValue, l'attribut value est toujours imprimé dans le DOM, et donc interprété. Ng-model devient alors annulé.

Un peu désagréable, mais utiliser ng-if fait le tour:

<input type="text" name="myInput" data-ng-if="value" data-ng-attr-value="{{myValue}}" data-ng-model="myModel" />
<input type="text" name="myInput" data-ng-if="!value" data-ng-model="myModel" />

Je recommanderais d'utiliser une vérification plus détaillée dans les directives ng-if :)

5
alexc

Aussi, vous pouvez utiliser une expression comme celle-ci:

<h1 ng-attr-contenteditable="{{ editMode ? true : false }}"></h1>
5
Kamuran Sönecek

J'ai en fait écrit un patch pour le faire il y a quelques mois (après que quelqu'un l'ait demandé dans #angularjs sur freenode).

Il ne sera probablement pas fusionné, mais il ressemble beaucoup à ngClass: https://github.com/angular/angular.js/pull/4269

Qu'il s'agisse d'une fusion ou non, les éléments existants de ng-attr- * conviennent probablement à vos besoins (comme d'autres l'ont déjà mentionné), bien qu'ils soient peut-être un peu moins pratiques que les fonctionnalités de type ngClass que vous proposez.

5
chronicsalsa

Juste au cas où vous auriez besoin d’une solution pour Angular 2, alors sa simple, utilisez la liaison de propriété comme ci-dessous, par ex. vous voulez que l'entrée soit lue uniquement de manière conditionnelle, puis ajoutez entre accolades l'attribut suivi du signe = et de l'expression.

<input [readonly]="mode=='VIEW'"> 
0
Sanjay Singh

En ce qui concerne le cas très simple où vous souhaitez appliquer (ou définir) un attribut uniquement si une certaine valeur d’entrée a été définie, c’est aussi simple que cela.

<my-element [conditionalAttr]="optionalValue || false">

C'est pareil que:

<my-element [conditionalAttr]="optionalValue ? optionalValue : false">

(Donc optionalValue est appliqué s'il est donné, sinon l'expression est fausse et l'attribut n'est pas appliqué.)

Exemple: j'ai eu le cas, où j'ai laissé appliquer une couleur mais aussi des styles arbitraires, où l'attribut color n'a pas fonctionné tel qu'il était déjà défini (même si la couleur @Input () n'était pas donnée):

@Component({
  selector: "rb-icon",
  styleUrls: ["icon.component.scss"],
  template: "<span class="ic-{{icon}}" [style.color]="color==color" [ngStyle]="styleObj" ></span>",
})
export class IconComponent {
   @Input() icon: string;
   @Input() color: string;
   @Input() styles: string;

   private styleObj: object;
...
}

Ainsi, "style.color" n'était défini que lorsque l'attribut color était présent, sinon l'attribut color de la chaîne "styles" pourrait être utilisé.

Bien entendu, cela pourrait également être réalisé avec

[style.color]="color" 

et

@Input color: (string | boolean) = false;
0
Zaphoid

Pour la validation du champ de saisie, vous pouvez faire:

<input ng-model="discount" type="number" ng-attr-max="{{discountType == '%' ? 100 : undefined}}">

Ceci appliquera l'attribut max à 100 uniquement si discountType est défini comme %

0
Nestor Britez