Кутовий 2 Показати та приховати елемент


174

У мене є проблема приховати і показати елемент залежно від булевої змінної у Angular 2.

це код для показу та приховування діва:

<div *ngIf="edited==true" class="alert alert-success alert-dismissible fade in" 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);
   }, 3000);
  }
}

Елемент прихований, коли запускається функція saveTodos, елемент відображається, але через 3 секунди, навіть якщо змінна повертається до помилкової, елемент не ховається. Чому?

Відповіді:


167

Вам слід використовувати * 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);
  }
}

Оновлення: під час зворотного дзвінка Timeout відсутнє посилання на зовнішню область застосування.

тому додайте .bind (це), як я додав вище

Питання: відредагований - це глобальна змінна. Яким би був ваш підхід у циклі * ngFor? - Блахірн

A: Я б додав редагування як властивість до об'єкта, над яким я повторюю.

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

editedє глобальною змінною. Яким би був ваш підхід у межах *ngFor-loop?
phil294

Відредагований не буде глобальною змінною, він належить до компонента. Відповідь я додам вище.
іноабрій

як отримати доступ до таймера глобально з сервісу?
Kumaresan Perumal

1
ngif викликає те, що деякі кутові компоненти матеріалу не ініціалізуються та працюють належним чином, як-от мат-paginator. Я думаю, що використання [приховано] кращий вибір для деяких випадків.
AmirHossein Rezaei

186

Є два варіанти залежно від того, чого ви хочете досягти:

  1. Ви можете використовувати приховану директиву, щоб показати або приховати елемент

    <div [hidden]="!edited" class="alert alert-success box-msg" role="alert">
      <strong>List Saved!</strong> Your changes has been saved.
    </div>
  2. Ви можете використовувати директиву управління ngIf для додавання або видалення елемента. Це відрізняється від прихованої директиви, оскільки вона не показує / приховує елемент, але додає / видаляє з DOM. Ви можете втратити збережені дані елемента. Це може бути кращим вибором для скасування компонента редагування.

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

Для вас проблема зміни через 3 секунди, це може бути пов'язано з несумісністю з setTimeout. Ви включили на свою сторінку бібліотеку angular2-polyfills.js?


5
[hidden]="edited"здається, це не має ніяких наслідків ...?
phil294

5
Якщо у вас є проблеми із прихованим, будь ласка, дотримуйтесь відповіді stackoverflow.com/a/35578093/873282 : [hidden] { display: none !important;}у вашому глобальному css.
коппор

30

Якщо вам не байдуже видалення Html Dom-Element, використовуйте * ngIf.

В іншому випадку використовуйте це:

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

14

Щоб дочірній компонент показав, я використовував *ngif="selectedState == 1"

Замість цього я використав [hidden]="selectedState!=1"

Це працювало для мене .. завантаження дочірнього компонента належним чином, а після приховування та скасування дочірнього компонента після його використання не було визначено.


6

Це хороший випадок використання директиви. Щось подібне напрочуд корисно.

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

Мені подобається ідея, але це повністю видалить елемент. Я змінив його , щоб приховати, так що ви можете використовувати його , але це не приховує елемент , імовірно з - за ngIfце true. Чи є спосіб встановити батьківську змінну, яка керує цим false?
priložл

Ви не можете просто додати прихований клас чи щось замість виклику видалити? Ця техніка досить загальна.
Алуан Хаддад

Я думаю, що проблема полягає ngIfбільше у тому, чи є елемент у DOM чи ні. Що я хочу, це таке: <div [hidden]="messages" [removeAfter]=3000>...де я показую / приховую повідомлення, якщо такі є, а потім видаляю повідомлення через 3 секунди, щоб користувачеві не довелося закривати вікно. Я додав вашу директиву вище і переключив її на виконання, hide()але вона не викликається, коли відображаються повідомлення. Як змусити його викликати події? @Output()і EventEmitter?
casel

4

Ми можемо це зробити, використовуючи наведений нижче фрагмент коду ..

Кутовий код:

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

Шаблон 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

Залежно від ваших потреб *ngIfабо того, [ngClass]="{hide_element: item.hidden}"де hide_elementзнаходиться клас CSS{ display: none; }

*ngIfможе викликати проблеми, якщо ви змінюєте змінні стану, *ngIfце видалення, у тих випадках, коли потрібно використовувати CSS display: none;.


0

Розчин @inoabrian вище працював для мене. Я зіткнувся з ситуацією, коли я оновив би свою сторінку, і мій прихований елемент знову з’явиться на моїй сторінці. Ось що я зробив, щоб вирішити це.

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

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

0

Просто додайте bind (це) у свою функцію setTimeout, яка почне працювати

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

і в зміні 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>

До

<div *ngIf="edited" class="alert alert-success alert-dismissible fade in" role="alert">
        <strong>List Saved!</strong> Your changes has been saved.
</div>
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.