紀錄本次專案一個需求解法。
需求
- 本次使用到 details 手風琴坐收闔的功能,並且裡面有放三個 input。
- 當 details 開啟時須帶出 input 的值。
- 當 details 收闔時要清空 input 的值,送出時為空值。
建立 HTML
因有多個 input
,故使用 formGroup
建立整份表單。
app.component.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| <form [formGroup]="form"> <details class="details"> <summary>詳細資料</summary>
<label> <input type="text" formControlName="firstInput" /> </label>
<label> <input type="text" formControlName="secondInput" /> </label>
<label> <input type="text" formControlName="thirdInput" /> </label> </details> </form>
|
app.component.ts
1 2 3 4 5 6 7 8 9 10 11 12
| form: FormGroup; ngOnInit() { this.createForm(); }
createForm() { this.form = this._fb.group({ firstInput: '', secondInput: '', thirdInput: '' }); }
|
建立完成後,就要來看一下 details 怎麼用。
details 屬性
details
預設打開為 true
,關閉為 false
,一開始我就想,不然我就用一個變數 isOpen
的變數來記錄 details
開關的狀態,但當我點擊 input
時,狀態會從 true
變成 false
,結果會把其他輸入好的欄位清空。
因為是第一次使用 details
標籤,發現 details
裡面的元素,會點擊一次就更改 details
的狀態,導致無法正確將值送出。
控制 details 狀態
經過一番查找後,發現 details
有一個屬性為 open
,所以就直接使用此屬性作為判斷,當 details
的屬性不是 open 的時候才清空 input 的值,在 details
上加上一個點擊事件。
app.component.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| <form [formGroup]="form"> <details class="details" (click)="detailsClick($event)"> <summary>詳細資料</summary>
<label> <input type="text" formControlName="firstInput"> </label>
<label> <input type="text" formControlName="secondInput"> </label>
<label> <input type="text" formControlName="thirdInput"> </label> </details> </form>
|
在寫入判斷:
app.component.ts
1 2 3 4 5 6 7 8 9 10
| detailsClick(e: any) { let details = this._el.nativeElement.querySelector('details'); if (!details.open) { this.form.get('firstInput').setValue(''); this.form.get('secondInput').setValue(''); this.form.get('thirdInput').setValue(''); } }
|
使用停止冒泡事件
經同事建議,還有另一個解法,就是直接阻止 input
的點擊冒泡事件。
只要在 input
上加上停止冒泡事件的方法,也可達到此效果。
app.componnet.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| <form [formGroup]="form"> <details class="details"> <summary>詳細資料</summary>
<label> <input type="text" formControlName="firstInput" (click)="stopDetailEvent($event)" /> </label>
<label> <input type="text" formControlName="secondInput" (click)="stopDetailEvent($event)" /> </label>
<label> <input type="text" formControlName="thirdInput" (click)="stopDetailEvent($event)" /> </label> </details> </form>
|
使用 stopPropagation()
方法。
app.component.ts
1 2 3
| stopDetailEvent(e: any) { e.stopPropagation(); }
|
Demo
連結
參考資料