Angular 2 Hiển thị và ẩn một phần tử


174

Tôi đang gặp vấn đề khi ẩn và hiển thị một phần tử tùy thuộc vào biến boolean trong Angular 2.

đây là mã để div hiển thị và ẩn:

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

biến được "chỉnh sửa" và nó được lưu trong thành phần của tôi:

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

Phần tử bị ẩn, khi hàm saveTodos khởi động, phần tử được hiển thị, nhưng sau 3 giây, ngay cả khi biến trở lại là false, phần tử không ẩn. Tại sao?

Câu trả lời:


167

Bạn nên sử dụng * ng If Directive

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

Cập nhật: bạn đang thiếu tham chiếu đến phạm vi bên ngoài khi bạn ở trong cuộc gọi lại Hết giờ.

vì vậy hãy thêm .bind (cái này) như tôi đã thêm ở trên

Q: chỉnh sửa là một biến toàn cục. Cách tiếp cận của bạn trong vòng * ngFor-loop là gì? - Blauhirn

Trả lời: Tôi sẽ thêm chỉnh sửa làm tài sản cho đối tượng tôi đang lặp lại.

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

editedlà một biến toàn cầu. Điều gì sẽ là cách tiếp cận của bạn trong một *ngFor-loop?
phil294

Chỉnh sửa sẽ không phải là một biến toàn cục, nó thuộc về thành phần. Tôi sẽ thêm câu trả lời ở trên.
inoabrian

Làm thế nào để truy cập bộ đếm thời gian trên toàn cầu từ dịch vụ?
Kumaresan Perumal

1
ngif gây ra một số thành phần vật liệu góc không khởi tạo và hoạt động đúng, như mat-paginator. Tôi nghĩ rằng sử dụng [hidden] là lựa chọn tốt hơn cho một số trường hợp.
AmirHossein Rezaei

186

Có hai lựa chọn tùy thuộc vào những gì bạn muốn đạt được:

  1. Bạn có thể sử dụng chỉ thị ẩn để hiển thị hoặc ẩn một phần tử

    <div [hidden]="!edited" class="alert alert-success box-msg" role="alert">
      <strong>List Saved!</strong> Your changes has been saved.
    </div>
  2. Bạn có thể sử dụng lệnh ng If control để thêm hoặc xóa phần tử. Điều này khác với chỉ thị ẩn vì nó không hiển thị / ẩn phần tử, nhưng nó thêm / xóa khỏi DOM. Bạn có thể mất dữ liệu chưa được lưu của phần tử. Nó có thể là sự lựa chọn tốt hơn cho một thành phần chỉnh sửa bị hủy bỏ.

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

Đối với bạn vấn đề thay đổi sau 3 giây, có thể là do không tương thích với setTimeout. Bạn đã bao gồm thư viện angular2-polyfills.js trong trang của mình chưa?


5
[hidden]="edited"dường như không có bất kỳ tác dụng ...?
phil294

5
Trong trường hợp bạn có vấn đề với ẩn, vui lòng làm theo câu trả lời của stackoverflow.com/a/35578093/873282 : [hidden] { display: none !important;}trong css toàn cầu của bạn.
koppor

30

Khi bạn không quan tâm đến việc xóa Phần tử Dom Html, hãy sử dụng * ng If.

Nếu không, sử dụng này:

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

14

Đối với thành phần con cho thấy tôi đang sử dụng *ngif="selectedState == 1"

Thay vào đó tôi đã sử dụng [hidden]="selectedState!=1"

Nó hoạt động với tôi .. tải thành phần con đúng cách và sau khi ẩn và bỏ ẩn thành phần con không được xác định sau khi sử dụng.


6

Đây là một trường hợp sử dụng tốt cho một chỉ thị. Một cái gì đó như thế này là hữu ích đáng ngạc nhiên.

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

Tôi thích ý tưởng, nhưng điều này sẽ loại bỏ hoàn toàn các yếu tố. Tôi đã thay đổi nó dễ dàng ngụy trang, vì vậy bạn có thể tái sử dụng nó nhưng điều đó không ẩn các yếu tố có lẽ do sự ngIftrue. Có cách nào để đặt biến của cha mẹ điều khiển biến này falsekhông?
thỉnh thoảng

Bạn có thể chỉ cần thêm một lớp ẩn hoặc một cái gì đó thay vì gọi loại bỏ? Kỹ thuật này khá chung chung.
Aluan Haddad

Tôi nghĩ vấn đề là ngIfnhiều hơn cho dù phần tử có trong DOM hay không. Điều tôi muốn là đây: <div [hidden]="messages" [removeAfter]=3000>...nơi tôi hiển thị / ẩn tin nhắn nếu có bất kỳ và sau đó xóa tin nhắn sau 3 giây để người dùng không phải đóng hộp. Tôi đã thêm chỉ thị của bạn ở trên và chuyển nó để thực hiện hide()nhưng nó không được gọi khi các thông báo được hiển thị. Làm thế nào để tôi có được nó để được mời trong sự kiện này? @Output()EventEmitter?
thỉnh thoảng

4

Chúng tôi có thể làm điều đó bằng cách sử dụng đoạn mã dưới đây ..

Mã góc:

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

Mẫu 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

Tùy thuộc vào nhu cầu của bạn, *ngIfhoặc [ngClass]="{hide_element: item.hidden}"nơi lớp CSS hide_element{ display: none; }

*ngIfcó thể gây ra sự cố nếu bạn đang thay đổi các biến trạng thái *ngIf, trong những trường hợp đó sử dụng CSSdisplay: none; là bắt buộc.


0

@inoabrian giải pháp trên làm việc cho tôi. Tôi gặp phải tình huống tôi sẽ làm mới trang của mình và yếu tố ẩn của tôi sẽ xuất hiện lại trên trang của tôi. Đây là những gì tôi đã làm để giải quyết nó.

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

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

0

Chỉ cần thêm liên kết (cái này) trong chức năng setTimeout của bạn, nó sẽ bắt đầu hoạt động

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

và trong thay đổi 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>

Đến

<div *ngIf="edited" class="alert alert-success alert-dismissible fade in" role="alert">
        <strong>List Saved!</strong> Your changes has been saved.
</div>
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.