Co jest równoważne ngShow i ngHide w Angular 2+?


Odpowiedzi:


949

Wystarczy powiązać z hiddenwłaściwością

[hidden]="!myVar"

Zobacz też

problemy

hidden ma jednak pewne problemy, ponieważ może powodować konflikt z CSS dla display właściwości.

Zobacz, jak somew przykładzie Plunkera nie ukrywa się, ponieważ ma swój styl

:host {display: block;}

zestaw. (To może zachowywać się inaczej w innych przeglądarkach - testowałem z Chrome 50)

obejście

Możesz to naprawić, dodając

[hidden] { display: none !important;}

Do globalnego stylu w index.html.

kolejna pułapka

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

są takie same jak

hidden="true"

i nie pokaże elementu.

hidden="false"przypisze ciąg, "false"który jest uważany za prawdziwy.
Tylko wartość falselub usunięcie atrybutu sprawi, że element będzie widoczny.

Użycie {{}}również przekształca wyrażenie w ciąg znaków i nie będzie działać zgodnie z oczekiwaniami.

Tylko wiązanie z []będzie działać zgodnie z oczekiwaniami, ponieważ falsejest przypisane jako falsezamiast "false".

*ngIf vs [hidden]

*ngIfskutecznie usuwa jego zawartość z DOM, a jednocześnie [hidden]modyfikuje displaywłaściwość i instruuje przeglądarkę, aby nie pokazywała zawartości, ale DOM nadal ją zawiera.


21
Używanie ukrytego nie jest w rzeczywistości zalecane. angularjs.blogspot.com/2016/04/…
Sam

7
*ngIfw większości przypadków może być poprawny, ale czasami naprawdę chcesz, aby element był tam, wizualnie ukryty. Styl CSS z [hidden]{display:none!important}pomocą. Tak na przykład Bootstrap upewnia się, że [hidden]elementy są faktycznie ukryte. Zobacz GitHub
CunningFatalist

Możesz napotkać jakiś problem, gdy używasz potoku (myStream | async) w * ngIf, który również używa potoku (myStream | async)
Pavel Blagodov

1
jesteś moim wybawcą! użycie * ngIf zresetuje pozycję DOM do góry, ale [ukryty] rozwiązał mój problem i zachował pozycję.
Santosh,

1
Jeden przypadek, w którym można by chcieć do użytku [ukryta] w * ngIf kiedy używasz HostListener (i chcą aby odróżnić kliknięć dokumentów vs event.target), gdy stara się pokazać i ukryć elementy (jak w przypadku upadków zwyczaj upuść)
akhouri

140

Użyj [hidden]atrybutu:

[hidden]="!myVar"

Lub możesz użyć *ngIf

*ngIf="myVar"

Są dwa sposoby pokazywania / ukrywania elementu. Jedyną różnicą jest: *ngIfusunie element z DOM, a jednocześnie [hidden]powie przeglądarce, aby pokazał / ukrył element za pomocą displaywłaściwości CSS , trzymając element w DOM.


3
[ukryty] dodaje warunkowo atrybut „ukryty” do elementu. Może to być również [cokolwiek] lub [ali]. Ważne jest tutaj, aby załadować regułę CSS, która wspomina o „ukrytych” atrybutach, które muszą być wyświetlane: brak
Gabriel

5
Pamiętaj: * ngI i [ukryte] różnią się zasadniczo. ngIf nie oceni zawartości wewnątrz bloku * ngIf, dopóki warunek nie będzie spełniony. Jest to szczególnie ważne, jeśli używasz asyncpotoku, ponieważ subskrypcja obserwowalnego zostanie dodana dopiero po spełnieniu warunku!
Dynalon

2
Jeszcze jedną rzeczą do wzięcia pod uwagę jest to, że * ngIf niszczy komponent i musi zostać odtworzony, a [ukryty] utrzymuje go przy życiu i zapamiętuje. Jeśli masz element wymagający dużej ilości zasobów, lepiej ukryć go niż go zniszczyć
Michael Kork.

1
to nie to samo.
Kamuran Sönecek

36

Znalazłem się w tej samej sytuacji z tą różnicą, co w moim przypadku, element był elastycznym pojemnikiem. Jeśli nie jest to twój przypadek, łatwym obejściem może być

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

w moim przypadku ze względu na fakt, że wiele obsługiwanych przez nas przeglądarek nadal potrzebuje prefiksu dostawcy, aby uniknąć problemów, wybrałem inne łatwe rozwiązanie

[class.is-loading]="isLoading"

gdzie wtedy CSS jest prosty jak

&.is-loading { display: none } 

aby opuścić następnie wyświetlany stan obsługiwany przez klasę domyślną.


1
Działa to dobrze z invalid-feedbackklasą bootstrap 4 .
Jess,

25

Przepraszam, muszę się nie zgodzić z powiązaniem z ukrytym, które jest uważane za niebezpieczne podczas korzystania z Angular 2. Jest tak, ponieważ ukryty styl można łatwo zastąpić, na przykład za pomocą

display: flex;

Zalecanym podejściem jest użycie * ngIf, który jest bezpieczniejszy. Więcej informacji można znaleźć na oficjalnym blogu Angular. 5 błędów początkujących, których należy unikać dzięki Angular 2

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

12
Myślę, że błędem nowicjusza jest powiedzenie, że coś jest złe, zanim poznasz dokładne wymagania. Jeśli ktoś nie chce, aby element został usunięty i zniszczony oraz dodany i odtworzony, *ngIfjest złym wyborem. Ale masz rację, że należy wziąć pod uwagę konsekwencje, a wskazanie pułapek jest zawsze dobrym pomysłem.
Günter Zöchbauer

2
Wiem co masz na myśli. To nie jest moje słowo, że to błąd początkujący, pochodzi z oficjalnego bloga Angular 2. Nie chcę nikogo urazić. Dzięki za wskazanie.
Tim Hong

9
Tak, nie sądzę ngIf, żeby dokładnie odpowiedziała na to pytanie. Chcę ukryć niektóre treści na stronie zawierającej <router-outlet>. Jeśli użyję ngIf, pojawia się błąd, że nie można znaleźć gniazdka. Potrzebuję ukryć ujście do momentu wczytania danych, a nieobecność do momentu załadowania danych.
Jason Swett

Zgadzam się z tobą, ale problem, który mam, polega na tym, że chcę pokazać formularz i wstawić w nim wartości, jeśli użyję * ng. Jeśli wystąpi błąd, że nie jest zdefiniowany, a właściwość ukryta działa dobrze
Hazem HASAN

@HazemHASAN, jasne. Rozumiem. Rozwiązanie jest zawsze warunkowe. W twoim przypadku nie wiem, czy można po prostu sprawdzić, czy formularz istnieje, zanim uruchomisz na nim inny kod. Chodzi o kompromis. Czy chcesz bezpieczniej ukryć formę, która nie zostanie w przyszłości przypadkowo skompensowana przez inną stylizację? A może wolisz nie sprawdzać, czy formularz istnieje?
Tim Hong

4

Jeśli twoim przypadkiem jest brak wyświetlania stylu, możesz również użyć dyrektywy ngStyle i bezpośrednio zmodyfikować wyświetlanie, zrobiłem to dla bootstrapu DropDown, UL na nim jest ustawiony na brak wyświetlania.

Stworzyłem więc zdarzenie kliknięcia do „ręcznego” przełączania UL, aby wyświetlić

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

Następnie w komponencie mam atrybut showDropDown: bool, który przełączam za każdym razem i na podstawie int, ustaw displayDDL dla stylu w następujący sposób

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

4

Zgodnie z dokumentacją Angular 1 ngShow i ngHide , obie te dyrektywy dodają styl cssdisplay: none !important; do elementu zgodnie z warunkiem tej dyrektywy (dla ngShow dodaje css dla fałszywej wartości, a dla ngHide dodaje css dla prawdziwej wartości).

Możemy osiągnąć to zachowanie, stosując dyrektywę 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>

Zauważ, że dla showzachowania w Angular2 musimy dodać !(nie) przed ngShowVal, a dla hidezachowania w Angular2 nie musimy dodawać !(nie) przed ngHideVal.


4
<div [hidden]="myExpression">

myExpression może być ustawiony na true lub false


2
<div hidden="{{ myExpression }}">To nie zadziała, ponieważ „myExpression” zostanie przekonwertowany na ciąg znaków do renderowania w html. Zarówno ciąg „prawda”, jak i „fałsz” są prawdziwe, więc zawsze będą ukryte
Viprus


3

w bootstrap 4.0 klasa "d-none" = "display: none! ważne;"

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

3

Dla każdego, kto natknie się na ten problem, tak to osiągnąłem.

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

Użyłem, 'visibility'ponieważ chciałem zachować przestrzeń zajmowaną przez element. Jeśli nie chcesz tego zrobić, możesz po prostu użyć go 'display'i ustawić na 'none';

Możesz powiązać go z elementem HTML, dynamicznie lub nie.

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

lub

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

2

Użyj ukrytego, jakbyś powiązał dowolny model z kontrolą i podaj dla niego css :

HTML:

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

CSS:

[hidden] {
   display: none;
}

2

to działało dla mnie:

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


1

dla mnie [hidden]=!varnigdy nie działał.

Więc, <div *ngIf="expression" style="display:none;">

I <div *ngIf="expression">Zawsze podawaj prawidłowe wyniki.


0

Istnieją dwa przykłady dokumentów Angular https://angular.io/guide/structural-directives#why-remove-rather-than-hide

Dyrektywa może ukryć niechciany akapit, ustawiając jego styl wyświetlania na none.

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

Możesz użyć [style.display] = "'block'", aby zastąpić ngShow, a [style.display] = "'none'", aby zastąpić ngHide.


0

Najlepszy sposób na rozwiązanie tego problemu, ngIf ponieważ dobrze zapobiegają renderowaniu tego elementu w interfejsie,

Jeśli użyjesz [hidden]="true"lub ukryjesz styl, ukryje [style.display]on tylko element z przodu, a ktoś może łatwo zmienić wartość i łatwo ją zobaczyć. Moim zdaniem najlepszym sposobem na ukrycie elementu jestngIf

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

a także Jeśli masz wiele elementów (musisz zaimplementować także inne), możesz użyć <ng-template>opcji

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

przykładowy kod szablonu ng


0

Jeśli chcesz po prostu użyć symetrycznych hidden/ showndyrektyw, które dostarczono z AngularJS, proponuję napisać dyrektywę atrybutów, aby uprościć takie szablony (testowane z 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';
  }
}

Wiele innych rozwiązań jest poprawnych. Państwo powinno używać *ngIfgdziekolwiek to możliwe. Użycie tego hiddenatrybutu może mieć zastosowanie nieoczekiwanych stylów, ale chyba że piszesz komponenty dla innych, prawdopodobnie wiesz, czy tak jest. Aby ta showndyrektywa zadziałała, należy również upewnić się, że dodano:

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

gdzieś w swoich globalnych stylach.

Dzięki nim możesz użyć dyrektywy w następujący sposób:

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

z wersją symetryczną (i przeciwną):

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

Aby dodać do rzeczy - powinieneś również nam prefiks taki jak [acmeShown]kontra kontra tylko[shown] .

Głównym powodem, dla którego użyłem showndyrektywy atrybutowej, jest konwersja kodu AngularJS na Angular -AND-, gdy ukryta zawartość zawiera komponenty kontenera, które powodują objazdy XHR w obie strony. Powodem, dla którego nie tylko używam, [hidden]="!myVar"jest to, że dość często jest to bardziej skomplikowane, jak: [hidden]="!(myVar || yourVar) && anotherVar" - yes I can invert that, but it is more error prone.[pokazano] `po prostu łatwiej jest myśleć.


-1

Aby ukryć i wyświetlić div na przycisku, kliknij kątowo 6.

Kod HTML

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

Kod komponentu .ts

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

to działa dla mnie i jest to sposób na zastąpienie ng-hide i ng-show w angular6.

cieszyć się...

Dzięki


Używasz ngIf - który różni się od ngShow. NgIf usunie / doda element z DOM. To nie to samo, co ngShow / ngHide, które dodają / usuwają style CSS do elementu.
Gil Epshtain

Przykład jest za długi i zbyt konkretny.
masterxilo
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.