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

更新:タイムアウトコールバック内にいるとき、外側のスコープへの参照がありません。

上で追加したように.bind(this)を追加します

Q:編集はグローバル変数です。* 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 2017年

Editedはグローバル変数ではなく、コンポーネントに属しています。上記の回答を追加します。
inoabrian 2017年

サービスからタイマーにグローバルにアクセスする方法は?
Kumaresan Perumal

1
ngifは、mat-paginatorのように、いくつかの角度のあるマテリアルコンポーネントが初期化されず、正しく機能しない原因となります。
AmirHossein Rezaei

186

達成したいことに応じて、2つのオプションがあります。

  1. hiddenディレクティブを使用して要素を表示または非表示にすることができます

    <div [hidden]="!edited" class="alert alert-success box-msg" role="alert">
      <strong>List Saved!</strong> Your changes has been saved.
    </div>
  2. ngIf制御ディレクティブを使用して、要素を追加または削除できます。これは、要素を表示/非表示にするのではなく、DOMを追加/削除するため、hiddenディレクティブとは異なります。要素の未保存のデータを失う可能性があります。キャンセルされた編集コンポーネントの場合は、より適切な選択になる可能性があります。

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

5
場合にはあなたが隠されたとの問題を抱えている、の答えに従ってくださいstackoverflow.com/a/35578093/873282を[hidden] { display: none !important;}あなたのグローバルCSSで。
koppor

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

私はアイデアが好きですが、これは要素を完全に削除します。私はそれを非表示に変更したので、再利用できますが、おそらくngIfisが原因で要素が非表示になりませんtrue。これを制御する親の変数をに設定する方法はありfalseますか?
occasl 2017年

removeを呼び出す代わりに、隠しクラスなどを追加することはできませんか?この手法はかなり一般的です。
Aluan Haddad 2017

問題はngIf、要素がDOM内にあるかどうかに関係があると思います。私が欲しいのはこれです:<div [hidden]="messages" [removeAfter]=3000>...メッセージがある場合にメッセージを表示/非表示にし、3秒後にメッセージを削除するので、ユーザーはボックスを閉じる必要がありません。上記のディレクティブを追加して、aに切り替えましたhide()が、メッセージが表示されても呼び出されません。イベントで呼び出されるようにするにはどうすればよいですか?@Output()EventEmitter
occasl 2017年

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}"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>
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.