Angular 2 Показать и скрыть элемент

174

У меня проблема с сокрытием и показом элемента, зависящего от логической переменной в Angular 2.

это код для отображения и скрытия div:

<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 секунды, даже если переменная возвращается в значение false, элемент не скрывается. Зачем?


источник

Ответы:

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 (это), как я добавил выше

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

A: Я бы добавил edit как свойство к объекту, над которым я перебираю.

<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);
  }
}
inoabrian
источник
editedэто глобальная переменная. Каков будет ваш подход в *ngFor-loop?
phil294
Отредактированный не будет глобальной переменной, он принадлежит компоненту. Я добавлю ответ выше.
иноабрианец
как получить доступ к таймеру глобально из службы?
Кумаресан Перумал
1
Примечание: некоторые угловые компоненты материала не могут быть инициализированы и работают должным образом, например, mat-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 на свою страницу?

Gentiane
источник
5
[hidden]="edited"кажется, не имеет никаких эффектов ...?
phil294
5
В случае, если у вас есть проблемы со скрытым, пожалуйста, следуйте ответу stackoverflow.com/a/35578093/873282 : [hidden] { display: none !important;}в вашем глобальном css.
Коппор
30

Если вам не нужно удалять HTML-элемент Dom, используйте * 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);
  }
}
Алуан Хаддад
источник
Мне нравится идея, но это удалит элемент полностью. Я изменил его, чтобы скрыть, чтобы вы могли использовать его повторно, но это не скрывает элемент, вероятно, из-за ngIfis true. Есть ли способ установить родительскую переменную, которая контролирует это false?
Occasl
Разве вы не можете просто добавить скрытый класс или что-то вместо вызова удаления? Эта техника довольно общая.
Алуан Хаддад
Я думаю, что проблема ngIfбольше в том, находится ли элемент в DOM или нет. Я хочу вот что: <div [hidden]="messages" [removeAfter]=3000>...где я показываю / скрываю сообщения, если они есть, а затем удаляю сообщения через 3 секунды, чтобы пользователю не приходилось закрывать окно. Я добавил вашу директиву выше и переключил ее на a, hide()но она не вызывается при отображении сообщений. Как мне заставить его быть вызванным на мероприятии? @Output()а EventEmitter?
Occasl
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>
Rejwanul Reja
источник
3

В зависимости от ваших потребностей, *ngIfили [ngClass]="{hide_element: item.hidden}"где класс CSS hide_elementявляется{ 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 (this) в функцию 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>
Мукеш Рават
источник