146 votes

Appliquer une directive de manière conditionnelle

J'utilise le matériel 2 pour ajouter md-raised-button . Je veux appliquer cette directive uniquement si une certaine condition devient vraie.

Par exemple :

<button md-raised-button="true"></button>

Un autre exemple : J'ai créé un formulaire dynamique réactif de base dans plunker. J'utilise formArrayName d'un formulaire réactif pour un tableau de contrôles. Je veux appliquer formArrayName seulement si une condition spécifique devient vraie, sinon n'ajoutez pas la directive formArrayName directive.

Voici un lien vers le site de l'entreprise .

0 votes

Oui md-raised-button c'est une directive attributaire ( material.angular.io/components/component/button )

0 votes

L'application de conditions sur les directives utilisées rendrait probablement l'AoT inutile, car vous ne pourriez pas compiler les modèles si l'application n'est pas en cours d'exécution.

101voto

Aldracor Points 926

Si vous avez simplement besoin d'ajouter un attribut afin de déclencher des règles CSS, vous pouvez utiliser la méthode ci-dessous : (ceci ne permet pas de créer/détruire dynamiquement une directive)

<button [attr.md-raised-button]="condition ? '' : null"></button>

J'ai appliqué la même chose à ton plunker : fourchette

Mise à jour :

Comment condition ? '' : null fonctionne comme valeur :

Lorsqu'il s'agit d'une chaîne vide ( '' ), on obtient attr.md-raised-button="" lorsque son null l'attribut n'existera pas.

Mise à jour : mise à jour de plunker : fourchette (problèmes de version corrigés, veuillez noter que la question était initialement basée sur angular 4)

0 votes

@Luke Oui, si vous voulez dire que par "(maintenant)" comme : depuis le 2017-01-06, soit 5 mois avant que la question ne soit posée. voir angulaire changelog 6ème point

0 votes

@Aldracor angular 5.2.1, ne fonctionne pas. Et je ne comprends pas pourquoi cela devrait ressembler à "condition ? '' : null" où les deux résultats sont fondamentalement faux. Qu'est-ce qui devrait être à la place de '' ? 'true' ne fonctionne pas non plus.

0 votes

@ArseniiFomin Vous devriez poser une nouvelle question pour cela. En ce qui concerne le fonctionnement, je vais modifier ma réponse pour l'expliquer.

69voto

LLL Points 1095

Je ne sais pas si vous pouvez appliquer des directives basées sur une condition, mais une solution de contournement serait d'avoir 2 boutons et les afficher en fonction d'une condition .

<button *ngIf="!condition"></button>
<button *ngIf="condition" md-raised-button></button> 

Edit : peut-être este sera utile.

17 votes

Merci pour votre réponse. Mais j'ai déjà utilisé cette technique dans l'exemple plunker que j'ai ajouté dans le détail des questions. C'est une bonne option mais pas une bonne idée si le code est complexe. Parce que cette technique ruine le concept de réutilisation. Vous pouvez voir mon exemple dans plunker et remarquer comment mon code est dupliqué à cause de cette approche. C'est pourquoi je ne veux pas utiliser cette technique. Je veux une meilleure solution pour pouvoir générer des éléments dynamiques avec.

1 votes

Je vois. Vous pourriez envelopper le code qui est dupliqué dans le composant.

3 votes

C'est une bonne idée mais malheureusement elle ne fonctionne pas dans le cas des formulaires réactifs. Avec les formulaires réactifs, un autre problème apparaît. Si je place l'entrée dans un composant distinct, Angular me demande d'ajouter [formGroup]="form" dans ce composant enfant également. Mais si je fais cela, ma liaison par tableau ne fonctionnera pas.

38voto

H.B. Points 76352

Comme nous l'avons déjà indiqué, cela ne semble pas possible. Une chose qui peut être utilisée pour au moins éviter une certaine duplication est la suivante ng-template . Cela vous permet d'extraire le contenu de l'élément affecté par l'option ngIf ramification.

Si vous souhaitez par exemple créer un composant de menu hiérarchique à l'aide d'Angular Material :

<!-- Button contents -->
<ng-template #contentTemplate>
    <mat-icon *ngIf="item.icon != null">{{ item.icon }}</mat-icon>
    {{ item.label }}
</ng-template>

<!-- Leaf button -->
<button *ngIf="item.children == null" mat-menu-item
    (click)="executeCommand()"
    [disabled]="enabled == false">
    <ng-container *ngTemplateOutlet="contentTemplate"></ng-container>
</button>
<!-- Node button -->
<ng-container *ngIf="item.children != null">
    <button mat-menu-item
        [matMenuTriggerFor]="subMenu">
        <ng-container *ngTemplateOutlet="contentTemplate"></ng-container>
    </button>

    <mat-menu #subMenu="matMenu">
        <menu-item *ngFor="let child of item.children" [item]="child"></menu-item>
    </mat-menu>
</ng-container>

Ici, la directive appliquée sous condition est matMenuTriggerFor qui ne doit s'appliquer qu'aux éléments de menu comportant des enfants. Le contenu du bouton est inséré aux deux endroits via ngTemplateOutlet .

13 votes

C'est la seule réponse qui permet au développeur d'utiliser des directives conditionnelles et de réutiliser le code.

25voto

Tiha Points 123

Cela peut arriver tardivement, mais c'est une méthode viable et élégante pour appliquer une directive de manière conditionnelle.

Dans la classe de directive, créez la variable d'entrée :

@Input('myDirective') options: any;

Lorsque vous appliquez la directive, définissez la propriété apply de la variable d'entrée :

<div [myDirective] = {apply: someCondition}></div>

Dans la méthode de la directive, on vérifie la variable this.options.apply et on applique la logique de la directive en fonction de la condition :

ngAfterViewInit(): void {
    if (!this.options.apply) {
        return;
    }

    // directive logic
}

7 votes

Cela ne fonctionne pas pour moi, car la directive existe toujours dans le composant, mais elle n'exécute aucune logique. J'aimerais que l'existence de la directive s'applique de manière conditionnelle, notamment parce qu'il existe une css qui vérifie la présence de cette directive.

0 votes

Vous avez un problème différent de celui énuméré ici (Appliquer la directive de manière conditionnelle). Postez votre problème et on vous aidera. Comme première idée, vous pourriez mettre la directive sur un div et mettre un ng-container avec un *ngIf autour de lui pour appliquer votre condition. ngIf supprime le nœud div du DOM, donc cela pourrait fonctionner. Je ne fais que supposer, vous devez poster votre problème avec des exemples de code/description pour que les gens puissent vous aider.

1 votes

Ce n'est pas une bonne solution. La directive est toujours initialisée.

12voto

Ankit Singh Points 15545

Comme d'autres l'ont également déclaré, directives ne peut pas être appliquée dynamiquement.

Cependant, si vous voulez simplement basculer md-button du style de plat a soulevé alors ceci

<button md-button [class.mat-raised-button]="isRaised">Toggle Raised Button</button>

ferait l'affaire. Plunker

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X