Angular 2 Pokaż i ukryj element


174

Mam problem z ukryciem i wyświetleniem elementu zależnego od zmiennej boolowskiej w Angular 2.

to jest kod elementu div, który ma pokazywać i ukrywać:

<div *ngIf="edited==true" class="alert alert-success alert-dismissible fade in" role="alert">
        <strong>List Saved!</strong> Your changes has been saved.
</div>

zmienna jest „edytowana” i jest przechowywana w moim komponencie:

export class AppComponent implements OnInit{

  (...)
  public edited = false;
  (...)
  saveTodos(): void {
   //show box msg
   this.edited = true;
   //wait 3 Seconds and hide
   setTimeout(function() {
       this.edited = false;
       console.log(this.edited);
   }, 3000);
  }
}

Element jest ukryty, po uruchomieniu funkcji saveTodos element jest pokazywany, ale po 3 sekundach, nawet jeśli zmienna wróci na fałsz, element się nie ukryje. Czemu?

Odpowiedzi:


167

Powinieneś użyć dyrektywy * ngIf

<div *ngIf="edited" class="alert alert-success box-msg" role="alert">
        <strong>List Saved!</strong> Your changes has been saved.
</div>


export class AppComponent implements OnInit{

  (...)
  public edited = false;
  (...)
  saveTodos(): void {
   //show box msg
   this.edited = true;
   //wait 3 Seconds and hide
   setTimeout(function() {
       this.edited = false;
       console.log(this.edited);
   }.bind(this), 3000);
  }
}

Aktualizacja: brakuje odwołania do zakresu zewnętrznego, gdy znajdujesz się wewnątrz wywołania zwrotnego Timeout.

więc dodaj .bind (this), tak jak dodałem powyżej

P: edytowana jest zmienną globalną. Jakie byłoby Twoje podejście do pętli * ngFor? - Blauhirn

Odp .: Dodałbym edit jako właściwość do obiektu, nad którym iteruję.

<div *ngFor="let obj of listOfObjects" *ngIf="obj.edited" class="alert alert-success box-msg" role="alert">
        <strong>List Saved!</strong> Your changes has been saved.
</div>


export class AppComponent implements OnInit{
   
  public listOfObjects = [
    {
       name : 'obj - 1',
       edit : false
    },
    {
       name : 'obj - 2',
       edit : false
    },
    {
       name : 'obj - 2',
       edit : false
    } 
  ];
  saveTodos(): void {
   //show box msg
   this.edited = true;
   //wait 3 Seconds and hide
   setTimeout(function() {
       this.edited = false;
       console.log(this.edited);
   }.bind(this), 3000);
  }
}

editedjest zmienną globalną. Jakie byłoby Twoje podejście w ramach *ngFor-loop?
— phil294

Edytowana nie byłaby zmienną globalną, należy do komponentu. Dodam odpowiedź powyżej.
— inoabrian

jak uzyskać globalny dostęp do timera z serwisu?
— Kumaresan Perumal

1
ngif powoduje, że niektóre komponenty materiału kątowego nie inicjują się i nie działają poprawnie, na przykład mat-paginator. Myślę, że użycie [hidden] jest lepszym wyborem w niektórych przypadkach.
— AmirHossein Rezaei

186

Istnieją dwie opcje w zależności od tego, co chcesz osiągnąć:

  1. Możesz użyć dyrektywy hidden, aby pokazać lub ukryć element

    <div [hidden]="!edited" class="alert alert-success box-msg" role="alert">
      <strong>List Saved!</strong> Your changes has been saved.
    </div>
  2. Możesz użyć dyrektywy ngIf control, aby dodać lub usunąć element. Różni się to od dyrektywy hidden, ponieważ nie pokazuje / nie ukrywa elementu, ale dodaje / usuwa z DOM. Możesz stracić niezapisane dane elementu. Może to być lepszy wybór w przypadku anulowanego komponentu edycji.

    <div *ngIf="edited" class="alert alert-success box-msg" role="alert"> 
      <strong>List Saved!</strong> Your changes has been saved.
    </div>

Dla Ciebie problem zmiany po 3 sekundach może być spowodowany niekompatybilnością z setTimeout. Czy umieściłeś na swojej stronie bibliotekę angular2-polyfills.js?


5
[hidden]="edited"nie wydaje się mieć żadnych efektów ...?
— phil294

5
W przypadku problemów z ukrywaniem, postępuj zgodnie z odpowiedzią na stackoverflow.com/a/35578093/873282 : [hidden] { display: none !important;}w swoim globalnym css.
— koppor

30

Jeśli nie zależy Ci na usunięciu elementu HTML Dom, użyj * ngIf.

W przeciwnym razie użyj tego:

<div [style.visibility]="(numberOfUnreadAlerts == 0) ? 'hidden' : 'visible' ">
   COUNTER: {{numberOfUnreadAlerts}} 
</div>

14

Aby komponent podrzędny był widoczny, używam *ngif="selectedState == 1"

Zamiast tego użyłem [hidden]="selectedState!=1"

U mnie zadziałało ... ładowanie komponentu potomnego poprawnie i po ukryciu i odznaczeniu komponentu potomnego nie było niezdefiniowane po użyciu tego.


6

To dobry przypadek użycia dyrektywy. Coś takiego jest zaskakująco przydatne.

@Directive({selector: '[removeAfter]'}) export class RemoveAfter {
  constructor(readonly element: ElementRef<HTMLElement>) { }

  /**
   * Removes the attributed element after the specified number of milliseconds. 
   * Defaults to (1000)
   */
  @Input() removeAfter = 1000;


  ngOnInit() {
    setTimeout(() => {
      this.element.nativeElement.remove();
    }, this.removeAfter);
  }
}

Podoba mi się ten pomysł, ale to całkowicie usunie element. Zmieniłem go, aby ukryć, więc możesz go użyć ponownie, ale to nie ukrywa elementu prawdopodobnie z powodu ngIfjest true. Czy istnieje sposób na ustawienie zmiennej nadrzędnej, która to kontroluje false?
— Occasl

Nie możesz po prostu dodać ukrytej klasy lub czegoś podobnego zamiast wywoływać usuwanie? Ta technika jest dość ogólna.
— Aluan Haddad,

Myślę, że problem polega ngIfbardziej na tym, czy element jest w DOM, czy nie. Chcę tego: <div [hidden]="messages" [removeAfter]=3000>...gdzie pokazuję / ukrywam wiadomości, jeśli takie są, a następnie usuwam wiadomości po 3 sekundach, aby użytkownik nie musiał zamykać okna. Dodałem twoją dyrektywę powyżej i przełączyłem ją na wykonanie a, hide()ale nie jest wywoływana, gdy wyświetlane są komunikaty. Jak sprawić, by został wywołany w wydarzeniu? @Output()i EventEmitter?
— Occasl

4

Możemy to zrobić za pomocą poniższego fragmentu kodu.

Kod kątowy:

 export class AppComponent {  
    toggleShowHide: string = "visible";  
 }

Szablon HTML:

  Enter text to hide or show item in bellow: 
  <input type="text" [(ngModel)]="toggleShowHide">
  <br>
  Toggle Show/hide:
  <div [style.visibility]="toggleShowHide">   
     Final Release Angular 2!
  </div>

3

W zależności od Twoich potrzeb *ngIflub miejsca, w [ngClass]="{hide_element: item.hidden}"którym hide_elementznajduje się klasa CSS{ display: none; }

*ngIfmoże powodować problemy, jeśli zmieniasz stan, zmienne *ngIfsą usuwane, w takich przypadkach display: none;wymagane jest użycie CSS .


0

@inoabrian powyżej rozwiązanie zadziałało dla mnie. Znalazłem się w sytuacji, w której odświeżyłem stronę, a ukryty element ponownie pojawił się na mojej stronie. Oto, co zrobiłem, aby go rozwiązać.

export class FooterComponent implements OnInit {
public showJoinTodayBtn: boolean = null;

ngOnInit() {
      if (condition is true) {
        this.showJoinTodayBtn = true;
      } else {
        this.showJoinTodayBtn = false;
      }
}

0

Po prostu dodaj bind (this) w swojej funkcji setTimeout, a zacznie działać

setTimeout(function() {
       this.edited = false;
       console.log(this.edited);
   }.bind(this), 3000);

i zmiana HTML

<div *ngIf="edited==true" class="alert alert-success alert-dismissible fade in" role="alert">
        <strong>List Saved!</strong> Your changes has been saved.
</div>

Do

<div *ngIf="edited" class="alert alert-success alert-dismissible fade in" role="alert">
        <strong>List Saved!</strong> Your changes has been saved.
</div>
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.