0%

Angular 筆記 - 控制 details 裡面的元素不被觸發

angular

紀錄本次專案一個需求解法。

需求

  • 本次使用到 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) {
//取得 details DOM 元素
let details = this._el.nativeElement.querySelector('details');
//判斷 details 屬性不是 open 的時候清空 input
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

連結

參考資料