Quel est l'équivalent de ngShow et ngHide dans Angular 2+?

570

J'ai un certain nombre d'éléments que je veux être visible sous certaines conditions.

Dans AngularJS j'écrirais

<div ng-show="myVar">stuff</div>

Comment puis-je faire cela dans Angular 2+?

Mihai Răducanu
la source
[hidden] = "! myVar" .. cela fonctionne en angulaire 2+
Pragati Dugar

Réponses:

951

Liez simplement à la hiddenpropriété

[hidden]="!myVar"

Voir également

problèmes

hiddena quelques problèmes, car il peut entrer en conflit avec CSS pour la displaypropriété.

Voyez comment somedans l' exemple de Plunker ne se cache pas parce qu'il a un style

:host {display: block;}

ensemble. (Cela pourrait se comporter différemment dans d'autres navigateurs - j'ai testé avec Chrome 50)

solution de contournement

Vous pouvez le corriger en ajoutant

[hidden] { display: none !important;}

Pour un style global dans index.html.

un autre écueil

hidden="false"
hidden="{{false}}"
hidden="{{isHidden}}" // isHidden = false;

sont les mêmes que

hidden="true"

et ne montrera pas l'élément.

hidden="false"affectera la chaîne "false"considérée comme véridique.
Seule la valeur falseou la suppression de l'attribut rendra l'élément visible.

L'utilisation {{}}convertit également l'expression en chaîne et ne fonctionnera pas comme prévu.

Seule la liaison avec []fonctionnera comme prévu car elle falseest affectée comme falseau lieu de "false".

*ngIf contre [hidden]

*ngIfsupprime efficacement son contenu du DOM tout en [hidden]modifiant la displaypropriété et demande uniquement au navigateur de ne pas afficher le contenu mais le DOM le contient toujours.

Günter Zöchbauer
la source
21
L'utilisation de masqué n'est en fait pas recommandée. angularjs.blogspot.com/2016/04/…
Sam
7
*ngIfpeut être la bonne façon dans la plupart des cas, mais parfois vous voulez réellement qu'un élément soit là, visuellement caché. Un style CSS avec [hidden]{display:none!important}aide. C'est, par exemple, comment Bootstrap s'assure que les [hidden]éléments sont réellement cachés. Voir GitHub
CunningFatalist
Vous pouvez rencontrer un problème lorsque vous utilisez le tuyau (myStream | async) à l'intérieur de * ngIf qui utilise également le tuyau (myStream | async)
Pavel Blagodov
1
tu es mon sauveur! l'utilisation de * ngIf réinitialisera la position du DOM en haut mais [caché] a résolu mon problème et préservé la position.
Santosh
1
Un cas où l'on peut vouloir utiliser [caché] sur * ngIf est lorsque vous utilisez HostListener (et que vous souhaitez différencier les clics sur le document vs event.target), lorsque vous essayez d'afficher et de masquer des éléments (comme avec des
listes
141

Utilisez l' [hidden]attribut:

[hidden]="!myVar"

Ou vous pouvez utiliser *ngIf

*ngIf="myVar"

Ce sont deux façons d'afficher / masquer un élément. La seule différence est: *ngIfsupprimera l'élément du DOM tandis que [hidden]dira au navigateur d'afficher / masquer un élément en utilisant la displaypropriété CSS en gardant l'élément dans DOM.

Ali Shahzad
la source
3
[caché] ajoute conditionnellement un attribut "caché" à l'élément. Il pourrait également s'agir de [n'importe quoi] ou [ali]. L'important ici est de charger une règle CSS qui mentionne les attributs "cachés" doit être affiché: aucun
Gabriel
5
Gardez à l'esprit: * ngIf et [hidden] sont fondamentalement différents. ngIf n'évaluera pas le contenu à l'intérieur du bloc * ngIf jusqu'à ce que la condition soit vraie. Ceci est particulièrement important si vous utilisez la asyncpipe, car l'abonnement à l'observable ne sera ajouté qu'après que la condition devienne vraie!
Dynalon
2
Une autre chose à prendre en considération est que * ngIf détruit le composant et qu'il doit être recréé, tandis que [caché] le maintient en vie et en mémoire. Si vous avez un composant gourmand en ressources, il peut être préférable de le cacher au lieu de le détruire
Michael Kork.
1
ce n'est pas la même chose.
Kamuran Sönecek
36

Je me retrouve dans la même situation avec la différence que dans mon cas, l'élément était un conteneur flexible.Si ce n'est pas votre cas, un travail facile pourrait être

[style.display]="!isLoading ? 'block' : 'none'"

dans mon cas, car de nombreux navigateurs que nous prenons en charge ont encore besoin du préfixe du fournisseur pour éviter les problèmes, j'ai opté pour une autre solution simple

[class.is-loading]="isLoading"

où le CSS est aussi simple que

&.is-loading { display: none } 

pour laisser ensuite l'état affiché géré par la classe par défaut.

Vale Steve
la source
1
Cela fonctionne bien avec la invalid-feedbackclasse bootstrap 4 .
Jess
25

Désolé, je ne suis pas d'accord avec la liaison à masqué, ce qui est considéré comme dangereux lors de l'utilisation d'Angular 2. En effet, le style masqué peut être facilement remplacé, par exemple en utilisant

display: flex;

L'approche recommandée consiste à utiliser * ngIf qui est plus sûr. Pour plus de détails, veuillez vous référer au blog officiel Angular. 5 erreurs de recrue à éviter avec Angular 2

<div *ngIf="showGreeting">
   Hello, there!
</div>
Tim Hong
la source
12
Je pense que c'est une erreur de débutant de dire que quelque chose ne va pas avant de connaître les exigences exactes. Si l'on ne veut pas qu'un élément soit supprimé, détruit, ajouté et recréé, *ngIfc'est un mauvais choix. Mais vous avez raison de considérer les conséquences et de signaler les pièges est toujours une bonne idée.
Günter Zöchbauer
2
Je vois ce que tu veux dire. Ce n'est pas ma parole, c'est une erreur de novice, elle est tirée du blog officiel d'Angular 2. Je ne veux offenser personne. Merci d'avoir souligné, cependant.
Tim Hong
9
Oui, je ne pense pas que cela ngIfréponde exactement à ce que cette question demande. Je souhaite masquer du contenu sur une page contenant un fichier <router-outlet>. Si j'utilise ngIf, j'obtiens une erreur indiquant qu'il ne trouve pas la prise. J'ai besoin que la prise soit cachée jusqu'à ce que mes données soient chargées, pas absente jusqu'à ce que mes données se chargent.
Jason Swett
Je suis d'accord avec vous, mais le problème que j'ai est que je veux montrer un formulaire et y mettre des valeurs si j'utilise le * ngSi j'ai l'erreur qu'il n'est pas défini et avec la propriété cachée, il fonctionne bien
Hazem HASAN
@HazemHASAN, bien sûr. Je comprends. La solution est toujours conditionnelle. Dans votre cas, vous ne savez pas s'il est possible de vérifier simplement si le formulaire est là avant d'exécuter un autre code par rapport à lui. C'est une question de compromis. Voulez-vous un moyen plus sûr de masquer accidentellement le formulaire qui ne sera pas compensé par un autre style à l'avenir? Ou préférez-vous avoir la commodité de ne pas vérifier si le formulaire existe?
Tim Hong
4

Si votre cas est que le style est afficher aucun, vous pouvez également utiliser la directive ngStyle et modifier directement l'affichage, je l'ai fait pour un BootDrap DropDown l'UL dessus est réglé pour afficher aucun.

J'ai donc créé un événement de clic pour basculer "manuellement" l'UL à afficher

<div class="dropdown">
    <button class="btn btn-default" (click)="manualtoggle()"  id="dropdownMenu1" >
    Seleccione una Ubicación
    <span class="caret"></span>
    </button>
    <ul class="dropdown-menu" [ngStyle]="{display:displayddl}">
        <li *ngFor="let object of Array" (click)="selectLocation(location)">{{object.Value}}</li>                                
     </ul>
 </div>    

Ensuite, sur le composant, j'ai l'attribut showDropDown: bool que je bascule à chaque fois, et en fonction de int, définissez le displayDDL pour le style comme suit

showDropDown:boolean;
displayddl:string;
manualtoggle(){
    this.showDropDown = !this.showDropDown;
    this.displayddl = this.showDropDown ? "inline" : "none";
}
Gary
la source
4

Selon la documentation Angular 1 de ngShow et ngHide , ces deux directives ajoutent le style css display: none !important;à l'élément en fonction de la condition de cette directive (pour ngShow ajoute le css sur une valeur fausse et pour ngHide ajoute le css pour la valeur vraie).

Nous pouvons obtenir ce comportement en utilisant la directive Angular 2 ngClass:

/* style.css */
.hide 
{
    display: none !important;
}

<!-- old angular1 ngShow -->
<div ng-show="ngShowVal"> I'm Angular1 ngShow... </div>

<!-- become new angular2 ngClass -->
<div [ngClass]="{ 'hide': !ngShowVal }"> I'm Angular2 ngShow... </div>

<!-- old angular2 ngHide -->
<div ng-hide="ngHideVal"> I'm Angular1 ngHide... </div>

<!-- become new angular2 ngClass -->
<div [ngClass]="{ 'hide': ngHideVal }"> I'm Angular2 ngHide... </div>

Notez que pour le showcomportement dans Angular2, nous devons ajouter !(pas) avant le ngShowVal, et pour le hidecomportement dans Angular2, nous n'avons pas besoin d'ajouter !(pas) avant le ngHideVal.

Gil Epshtain
la source
4
<div [hidden]="myExpression">

myExpression peut être définie sur true ou false

Niyaz
la source
2
<div hidden="{{ myExpression }}">Cela ne fonctionnera pas, car "myExpression" sera converti en une chaîne à rendre en html. Les chaînes "true" et "false" sont véridiques, elles seront donc toujours cachées
Viprus
3

Si vous utilisez Bootstrap, c'est aussi simple que cela:

<div [class.hidden]="myBooleanValue"></div>
Gian Marco Gherardi
la source
3
Dans bootstrap 4, l'utilisation [hidden]fait la même chose, donc je recommande[hidden]
Vahid
3

dans bootstrap 4.0, la classe "d-none" = "display: none! important;"

<div [ngClass]="{'d-none': exp}"> </div>
63RMAN
la source
3

Pour quiconque tombe sur ce problème, c'est comme ça que je l'ai fait.

import {Directive, ElementRef, Input, OnChanges, Renderer2} from "@angular/core";

@Directive({
  selector: '[hide]'
})
export class HideDirective implements OnChanges {
  @Input() hide: boolean;

  constructor(private renderer: Renderer2, private elRef: ElementRef) {}

  ngOnChanges() {
    if (this.hide) {
      this.renderer.setStyle(this.elRef.nativeElement, 'visibility', 'hidden');
    } else {
      this.renderer.setStyle(this.elRef.nativeElement, 'visibility', 'visible');
    }
  }
}

J'ai utilisé 'visibility'parce que je voulais conserver l'espace occupé par l'élément. Si vous ne le souhaitez pas, vous pouvez simplement l'utiliser 'display'et le régler sur 'none';

Vous pouvez le lier à votre élément html, dynamiquement ou non.

<span hide="true"></span>

ou

<span [hide]="anyBooleanExpression"></span>
Anjil Dhamala
la source
2

Utilisez caché comme vous liez n'importe quel modèle avec contrôle et spécifiez css pour cela:

HTML:

<input type="button" class="view form-control" value="View" [hidden]="true" />

CSS:

[hidden] {
   display: none;
}
Sandip - Développeur Full Stack
la source
2

C'est ce qui a fonctionné pour moi:

<div [style.visibility]="showThis ? 'visible' : 'hidden'">blah</div>
Alex
la source
1
<div [hidden]="flagValue">
---content---
</div>
Chirag
la source
1

pour moi, [hidden]=!varn'a jamais fonctionné.

Donc, <div *ngIf="expression" style="display:none;">

Et, <div *ngIf="expression">donnez toujours des résultats corrects.

Priyanka Arora
la source
0

Il existe deux exemples sur les documents angulaires https://angular.io/guide/structural-directives#why-remove-rather-than-hide

Une directive pourrait masquer le paragraphe indésirable à la place en définissant son style d'affichage sur aucun.

<p [style.display]="'block'">
  Expression sets display to "block".
  This paragraph is visible.
</p>

<p [style.display]="'none'">
  Expression sets display to "none".
  This paragraph is hidden but still in the DOM.
</p>

Vous pouvez utiliser [style.display] = "'block'" pour remplacer ngShow et [style.display] = "'none'" pour remplacer ngHide.

koo
la source
0

Meilleure façon de résoudre ce problème en utilisant ngIf Parce que cela empêche bien d'obtenir le rendu de cet élément en front-end,

Si vous utilisez [hidden]="true"ou style masquer, [style.display]il ne masquera l'élément dans le front-end et quelqu'un peut changer la valeur et la voir facilement, à mon avis, la meilleure façon de masquer l'élément estngIf

<div *ngIf="myVar">stuff</div>

et aussi Si vous avez plusieurs éléments (besoin d'implémenter autre chose aussi) vous pouvez utiliser l' <ng-template>option

<ng-container *ngIf="myVar; then loadAdmin else loadMenu"></ng-container>
<ng-template #loadMenu>
     <div>loadMenu</div>
</ng-template>

<ng-template #loadAdmin>
     <div>loadAdmin</div>
</ng-template>  

exemple de code ng-template

Déc
la source
0

Si vous souhaitez simplement utiliser les directives symétriques hidden/ shownfournies avec AngularJS, je suggère d'écrire une directive d'attribut pour simplifier les modèles comme cela (testé avec Angular 7):


import { Directive, Input, HostBinding } from '@angular/core';

@Directive({ selector: '[shown]' })
export class ShownDirective {
  @Input() public shown: boolean;

  @HostBinding('attr.hidden')
  public get attrHidden(): string | null {
    return this.shown ? null : 'hidden';
  }
}

De nombreuses autres solutions sont correctes. Vous devez utiliser *ngIflorsque cela est possible. L'utilisation de l' hiddenattribut peut avoir des styles inattendus appliqués, mais sauf si vous écrivez des composants pour d'autres, vous savez probablement si c'est le cas. Donc, pour que cette showndirective fonctionne, vous devez également vous assurer que vous ajoutez:

[hidden]: {
  display: none !important;
}

à vos styles globaux quelque part.

Avec ceux-ci, vous pouvez utiliser la directive comme suit:

<div [shown]="myVar">stuff</div>

avec la version symétrique (et opposée) comme ceci:

<div [hidden]="myVar">stuff</div>

Pour ajouter aux épaules - vous devriez également nous utiliser un préfixe comme si [acmeShown]vs vs juste [shown].

La principale raison pour laquelle j'ai utilisé une showndirective d'attribut est pour convertir le code AngularJS en Angular -AND- lorsque le contenu qui est masqué contient des composants de conteneur qui provoquent des allers-retours XHR. La raison pour laquelle je ne me contente pas d'utiliser [hidden]="!myVar"est que, souvent, c'est plus compliqué comme: [hidden]="!(myVar || yourVar) && anotherVar" - yes I can invert that, but it is more error prone.[montré] `est simplement plus facile à penser.

nephiw
la source
-1

Pour masquer et afficher le bouton div sur, cliquez sur angulaire 6.

Code HTML

<button (click)=" isShow=!isShow">FormatCell</button>
<div class="ruleOptionsPanel" *ngIf=" isShow">
<table>
<tr>
<td>Name</td>
<td>Ram</td>
</tr>
</table>
</div>

Composant .ts Code

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent{
 isShow=false;
  }

cela fonctionne pour moi et c'est un moyen de remplacer ng-hide et ng-show dans angular6.

prendre plaisir...

Merci

Manoj Gupta
la source
Vous utilisez ngIf - qui est différent de ngShow. NgIf supprimera / ajoutera l'élément du DOM. Ce n'est pas la même chose que ngShow / ngHide qui n'ajoutera / supprimera que les styles Css à l'élément.
Gil Epshtain
L'exemple est trop long et trop précis.
masterxilo