問題
項目中遇到一個問題,有一個過濾查詢的面板,需要通過一個展開折疊的button,來控制它的show 和 hide。這個面板中,有一個Select 組件,一個 input 查詢輸入框。
原來代碼是:
<div class="accordion-content" *ngIf="showFilter"><div class="pTop"><div app-choosen-select [options]="selectCompOptions" (selectedDataChange)="onFilterChange($event)" class="cpu-select"></div></div><div class="form-group"><input type="text" placeholder="查詢" [(ngModel)]="searchTxt" (ngModelChange)="searchNode()"></div>
</div>
然后發現,每次點擊 toggle button,都會觸發一次onFilterChange()
事件,因為 app-choosen-select
組件在初始化時會觸發傳入的 selectedDataChange
事件。從而影響到預期的結果。
解決方案
將 `*ngIf` 改成 `hidden`。
<div class="accordion-content" [hidden]="!showFilter"><div class="pTop"><div app-choosen-select [options]="selectCompOptions" (selectedDataChange)="onFilterChange($event)" class="cpu-select"></div></div><div class="form-group"><input type="text" placeholder="查詢" [(ngModel)]="searchTxt" (ngModelChange)="searchNode()"></div>
</div>
What is the difference between *ngIf and [hidden]?
參考:https://stackoverflow.com/questions/43034758/what-is-the-difference-between-ngif-and-hidden
ngIf
is a structural directive, it creates/destroys content inside the DOM. The[hidden]
statement just hides/shows the content with css, i.e. adding/removing display:none to the element's style.
也就是,*ngIf=true
時,會重新創建其內部的 DOM 元素包括子組件,同時如果設置了數據綁定、事件綁定,也會重新綁定;*ngIf=false
時,會銷毀其內部的DOM 元素和子組件,也會銷毀綁定的數據和綁定的事件。
但是,[hidden]=true
,只是隱藏了DOM元素和子組件,并沒有重新初始化,綁定的數據和事件都還在的。
So [hidden] is better used when we want the show/hide status to change frequently, for example on a button click event, so we do not have to load the data every time the button is clicked, just changing its hidden attribute would be enough.
Note that the performance difference may not be visible with small data, only with larger objects.
所以,在這樣的toggle 某一個元素的情況下,使用[hidden]
比較好。