Was entspricht ngShow und ngHide in Angular 2+?


570

Ich habe eine Reihe von Elementen, die ich unter bestimmten Bedingungen sichtbar machen möchte.

In AngularJS würde ich schreiben

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

Wie kann ich das in Angular 2+ machen?


[hidden] = "! myVar" .. dies funktioniert in Winkel 2+
Pragati Dugar

Antworten:


950

Binden Sie einfach an die hiddenEigenschaft

[hidden]="!myVar"

Siehe auch

Probleme

hiddenhat jedoch einige Probleme, da es zu Konflikten mit CSS für die displayEigenschaft kommen kann.

Sehen Sie, wie someim Plunker-Beispiel nicht versteckt wird, weil es einen Stil hat

:host {display: block;}

einstellen. (Dies kann sich in anderen Browsern anders verhalten - ich habe mit Chrome 50 getestet.)

Problemumgehung

Sie können es beheben, indem Sie hinzufügen

[hidden] { display: none !important;}

Zu einem globalen Stil in index.html.

eine weitere Falle

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

sind die gleichen wie

hidden="true"

und zeigt das Element nicht an.

hidden="false"weist die Zeichenfolge zu, "false"die als wahr angesehen wird.
Nur der Wert falseoder das Entfernen des Attributs macht das Element tatsächlich sichtbar.

Die Verwendung {{}}konvertiert auch den Ausdruck in eine Zeichenfolge und funktioniert nicht wie erwartet.

Nur das Binden mit []funktioniert wie erwartet, da dies falseals falseanstelle von zugewiesen wird "false".

*ngIf vs. [hidden]

*ngIfEntfernt effektiv seinen Inhalt aus dem DOM, während [hidden]die displayEigenschaft geändert wird, und weist den Browser nur an, den Inhalt nicht anzuzeigen, aber das DOM enthält ihn weiterhin.


21
Die Verwendung von Hidden wird eigentlich nicht empfohlen. angularjs.blogspot.com/2016/04/…
Sam

7
*ngIfIn den meisten Fällen mag dies der richtige Weg sein, aber manchmal möchten Sie tatsächlich, dass ein Element visuell verborgen ist. Ein CSS-Stil mit [hidden]{display:none!important}hilft. So stellt Bootstrap beispielsweise sicher, dass [hidden]Elemente tatsächlich ausgeblendet werden. Siehe GitHub
CunningFatalist

Sie können auf ein Problem stoßen, wenn Sie die Pipe (myStream | async) innerhalb von * ngIf verwenden, die auch die Pipe (myStream | async) verwendet
Pavel Blagodov

1
Du bist mein Retter! Mit * ngIf wird die DOM-Position nach oben zurückgesetzt, aber [versteckt] hat mein Problem gelöst und die Position beibehalten.
Santosh

1
Ein Fall, in dem Sie [versteckt] über * ngIf verwenden möchten, ist, wenn Sie HostListener verwenden (und Dokumentklicks von event.target unterscheiden möchten), wenn Sie versuchen, Elemente anzuzeigen und auszublenden (wie bei benutzerdefinierten Dropdown-
Listen

140

Verwenden Sie das [hidden]Attribut:

[hidden]="!myVar"

Oder Sie können verwenden *ngIf

*ngIf="myVar"

Dies sind zwei Möglichkeiten, um ein Element ein- oder auszublenden. Der einzige Unterschied besteht darin *ngIf, dass das Element aus dem DOM entfernt [hidden]wird, während der Browser angewiesen wird, ein Element mithilfe der CSS- displayEigenschaft anzuzeigen / auszublenden, indem das Element im DOM belassen wird.


3
[versteckt] fügt dem Element bedingt ein Attribut "versteckt" hinzu. Es könnte auch [was auch immer] oder [ali] sein. Das Wichtigste hier ist, eine CSS-Regel zu laden, die erwähnt, dass "versteckte" Attribute angezeigt werden müssen: keine
Gabriel

5
Denken Sie daran: * ngIf und [hidden] unterscheiden sich grundlegend. ngIf wertet den Inhalt innerhalb des * ngIf-Blocks erst aus, wenn die Bedingung erfüllt ist. Dies ist besonders wichtig, wenn Sie die asyncPipe verwenden, da das Abonnement für das Observable erst hinzugefügt wird, wenn die Bedingung erfüllt ist!
Dynalon

2
Eine weitere zu berücksichtigende Sache ist, dass * ngIf die Komponente zerstört und sie neu erstellt werden muss, während [versteckt] sie am Leben und im Speicher hält. Wenn Sie eine ressourcenintensive Komponente haben, ist es möglicherweise vorzuziehen, sie auszublenden, anstatt sie zu zerstören
Michael Kork.

1
Sie sind nicht dasselbe.
Kamuran Sönecek

36

Ich befinde mich in der gleichen Situation mit dem Unterschied, dass in meinem Fall das Element ein flexibler Container war. Wenn dies nicht Ihr Fall ist, könnte eine einfache Lösung sein

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

In meinem Fall habe ich mich für eine andere einfache Lösung entschieden, da viele von uns unterstützte Browser immer noch das Herstellerpräfix benötigen, um Probleme zu vermeiden

[class.is-loading]="isLoading"

wo dann ist das CSS einfach wie

&.is-loading { display: none } 

um dann den angezeigten Status zu verlassen, der von der Standardklasse behandelt wird.


1
Dies funktioniert gut mit der Bootstrap 4- invalid-feedbackKlasse.
Jess

25

Entschuldigung, ich muss der Bindung an versteckt nicht zustimmen, was bei Verwendung von Angular 2 als unsicher angesehen wird. Dies liegt daran, dass der versteckte Stil beispielsweise mit einfach überschrieben werden kann

display: flex;

Der empfohlene Ansatz ist die Verwendung von * ngIf, was sicherer ist. Weitere Informationen finden Sie im offiziellen Angular-Blog. 5 Anfängerfehler, die mit Angular 2 zu vermeiden sind

<div *ngIf="showGreeting">
   Hello, there!
</div>

12
Ich denke, es ist ein Anfängerfehler, zu sagen, dass etwas schlecht ist, bevor man die genauen Anforderungen kennt. Wenn man nicht möchte, dass ein Element entfernt und zerstört und hinzugefügt und neu erstellt wird, *ngIfist dies eine schlechte Wahl. Sie haben jedoch Recht, dass die Konsequenzen berücksichtigt werden müssen, und es ist immer eine gute Idee, auf Fallstricke hinzuweisen.
Günter Zöchbauer

2
Ich weiß, was du meinst. Es ist nicht mein Wort darüber, dass es ein Anfängerfehler ist, es stammt aus dem offiziellen Angular 2-Blog. Ich will niemanden beleidigen. Vielen Dank für den Hinweis.
Tim Hong

9
Ja, ich denke nicht ngIfgenau, was diese Frage stellt. Ich möchte einige Inhalte auf einer Seite ausblenden, die a enthält <router-outlet>. Wenn ich benutze ngIf, erhalte ich die Fehlermeldung, dass die Steckdose nicht gefunden werden kann. Ich muss die Steckdose ausblenden, bis meine Daten geladen sind, und nicht fehlen, bis meine Daten geladen sind.
Jason Swett

Ich stimme Ihnen zu, aber das Problem, das ich habe, ist, dass ich ein Formular anzeigen und Werte darin einfügen möchte, wenn ich * ngI verwende. Wenn ich den Fehler habe, dass es nicht definiert ist und mit der versteckten Eigenschaft gut funktioniert
Hazem HASAN

@ HasemHASAN, sicher. Ich verstehe. Die Lösung ist immer bedingt. In Ihrem Fall sind Sie sich nicht sicher, ob es möglich ist, nur zu überprüfen, ob das Formular vorhanden ist, bevor Sie einen anderen Code dafür ausführen. Es geht nur um den Kompromiss. Möchten Sie das Formular sicherer verbergen, ohne dass es in Zukunft versehentlich durch ein anderes Styling ausgeglichen wird? Oder möchten Sie lieber nicht prüfen, ob das Formular vorhanden ist?
Tim Hong

4

Wenn Sie der Meinung sind, dass der Stil "Keine anzeigen" ist, können Sie auch die Anweisung "ngStyle" verwenden und die Anzeige direkt ändern. Bei einem Bootstrap-DropDown ist die UL darauf so eingestellt, dass keine angezeigt wird.

Also habe ich ein Klickereignis zum "manuellen" Umschalten des UL erstellt, um es anzuzeigen

<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>    

Dann habe ich für die Komponente showDropDown: bool-Attribut, das ich jedes Mal umschalte, und basierend auf int die displayDDL für den Stil wie folgt festgelegt

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

4

Gemäß der Angular 1-Dokumentation von ngShow und ngHide fügen beide Direktiven den CSS-Stil display: none !important;dem Element gemäß der Bedingung dieser Direktive hinzu (für ngShow wird das CSS für den falschen Wert hinzugefügt, und für ngHide wird das CSS für den wahren Wert hinzugefügt).

Wir können dieses Verhalten mit der Angular 2-Direktive ngClass erreichen:

/* 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>

Beachten Sie, dass showwir für das Verhalten in Angular2 !(nicht) vor dem ngShowVal hinzufügen müssen und für das hideVerhalten in Angular2 nicht! (nicht) vor dem ngHideVal hinzufügen müssen.


4
<div [hidden]="myExpression">

myExpression kann auf true oder false gesetzt sein


2
<div hidden="{{ myExpression }}">Dies funktioniert nicht, da "myExpression" in eine Zeichenfolge konvertiert wird, die im HTML-Code gerendert wird. Sowohl die Zeichenfolge "wahr" als auch "falsch" sind wahr, daher wird sie immer verborgen
bleiben


3

in Bootstrap 4.0 die Klasse "d-none" = "display: none! important;"

<div [ngClass]="{'d-none': exp}"> </div>

3

Für alle anderen, die über dieses Problem stolpern, habe ich es so erreicht.

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');
    }
  }
}

Ich habe verwendet, 'visibility'weil ich den Platz, den das Element einnimmt, erhalten wollte. Wenn Sie dies nicht möchten, können Sie es einfach verwenden 'display'und auf einstellen 'none'.

Sie können es dynamisch oder nicht dynamisch an Ihr HTML-Element binden.

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

oder

<span [hide]="anyBooleanExpression"></span>

2

Verwenden Sie versteckt, wie Sie ein Modell mit Steuerelement binden und CSS dafür angeben :

HTML:

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

CSS:

[hidden] {
   display: none;
}

2

Das hat bei mir funktioniert:

<div [style.visibility]="showThis ? 'visible' : 'hidden'">blah</div>


1

für mich [hidden]=!varhat noch nie funktioniert.

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

Und <div *ngIf="expression">geben Sie immer die richtigen Ergebnisse.


0

Es gibt zwei Beispiele für Angular-Dokumente: https://angular.io/guide/structural-directives#why-remove-rather-than-hide

Eine Direktive könnte stattdessen den unerwünschten Absatz ausblenden, indem sie ihren Anzeigestil auf none setzt.

<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>

Sie können [style.display] = "'block'" verwenden, um ngShow zu ersetzen, und [style.display] = "'none'", um ngHide zu ersetzen.


0

Der beste Weg, um dieses Problem zu lösen, indem Sie ngIf verhindern, dass dieses Element im Front-End gerendert wird.

Wenn Sie [hidden]="true"hide verwenden oder stylen [style.display], wird das Element nur im Front-End ausgeblendet, und jemand kann den Wert ändern und leicht anzeigen. Meiner Meinung nach ist es am besten, das Element auszublendenngIf

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

und auch Wenn Sie mehrere Elemente haben (müssen auch andere implementieren), können Sie die <ng-template>Option verwenden

<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>  

Beispiel für einen ng-Template-Code


0

Wenn Sie nur die Symmetrics hidden/ shownDirektiven verwenden möchten, mit denen AngularJS geliefert wurde, empfehle ich, eine Attribut-Direktive zu schreiben, um die Vorlagen wie folgt zu vereinfachen (getestet mit 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';
  }
}

Viele der anderen Lösungen sind korrekt. Sie sollten verwenden, *ngIfwo immer dies möglich ist. Bei Verwendung des hiddenAttributs können unerwartete Stile angewendet werden. Wenn Sie jedoch keine Komponenten für andere schreiben, wissen Sie wahrscheinlich, ob dies der Fall ist. Damit diese shownDirektive funktioniert, sollten Sie außerdem Folgendes hinzufügen:

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

zu Ihren globalen Stilen irgendwo.

Mit diesen können Sie die Direktive wie folgt verwenden:

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

mit der symmetrischen (und entgegengesetzten) Version wie folgt:

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

Um die Schultern zu ergänzen, sollten Sie uns auch ein Präfix wie so [acmeShown]vs just geben [shown].

Der Hauptgrund, warum ich eine shownAttributanweisung verwendet habe, ist die Konvertierung von AngularJS-Code in Angular -AND-, wenn der ausgeblendete Inhalt Containerkomponenten enthält, die XHR-Roundtrips verursachen. Der Grund, den ich nicht nur benutze, [hidden]="!myVar"ist, dass es oft genug komplizierter ist wie: [hidden]="!(myVar || yourVar) && anotherVar" - yes I can invert that, but it is more error prone.[gezeigt] `ist einfach einfacher zu überlegen.


-1

Um die Schaltfläche div on ein- und auszublenden, klicken Sie in Winkel 6.

HTML Quelltext

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

Component .ts Code

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

Dies funktioniert für mich und es ist eine Möglichkeit, ng-hide und ng-show in angle6 zu ersetzen.

genießen...

Vielen Dank


Sie verwenden ngIf - was sich von ngShow unterscheidet. NgIf entfernt / fügt das Element aus dem DOM hinzu. Dies ist nicht dasselbe wie ngShow / ngHide, bei dem dem Element nur CSS-Stile hinzugefügt / entfernt werden.
Gil Epshtain

Das Beispiel ist zu lang und zu spezifisch.
Masterxilo
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.