Angular 12 中的 Dropdown(select) 在浏览器中手动更改后自动 selecting 第一项
Dropdown(select) in Angular 12 is automatically selecting first item, after manual change in browser
给定以下组件 HTML:
<select (change)="leagueChoosen($event)">
<option disabled></option>
<option *ngFor="let league of leagues.entries()" value={{league[1]}}> {{league[0]} </option>
</select>
联赛所在位置:
leagues:Map<string,number> = new Map([["PORTUGAL 1", 35],["BELGIUM 1", 3], ["GERMANY 2", 18]])
所以,问题是,每当我 select 在我的下拉列表中手动选择一个项目时,后台逻辑是正确的 [函数 leagueChoosen() ] 正在正确地完成它的工作,但是,在那之后自动第一个项目列表中的(空白的)是 select 自动编辑的,因此下拉文本是空白的。
更新:(我也是 Angular 的新人)
有 3 个组件:sidebar、content、wrapper(前两个组件的父组件)
<!-- sidebar -->
<select (change)="leagueChoosen($event)">
<option></option>
<option *ngFor="let league of leagues.entries()" value={{league[1]}}>{{league[0]}}
</option>
</select>
<!-- content -->
<table>
<caption>Football<app-button (btnClick)="Delete()" text="Delete" float="right"></app-button></caption>
<thead>
<th style="text-align: left;">{{data[0]==undefined?"":data[0].liga_header}}</th>
<th colspan="3">Конечен тип</th>
<th colspan="3">Голови</th>
</thead>
<tbody>
<tr *ngFor="let match of data">
<td>{{match==undefined?"":match.broj}} - {{match==undefined?"":match.datum_vreme.substring(6,match.datum_vreme.length - 2) | date:"HH:mm"}} - {{match==undefined?"":match.tim1}} - {{match==undefined?"":match.tim2}}</td>
<td>{{match==undefined?"":match.k1}}</td>
<td>{{match==undefined?"":match.kx}}</td>
<td>{{match==undefined?"":match.k2}}</td>
<td>{{match==undefined?"":match.kgg3plus}}</td>
<td>{{match==undefined?"":match.k0do2}}</td>
<td>{{match==undefined?"":match.k3plus}}</td>
</tr>
</tbody>
<!-- wrapper -->
<div class='sidebar'>
<app-sidebar (liClick)="leagueChoosen($event)"></app-sidebar>
</div>
<div class='content'>
<ul>
<li *ngFor="let league of data"><app-content
(dlt)="Delete(league)"
[data]="league">
</app-content>
</li>
</ul>
</div>
问题似乎出在您的 html 中,您没有为 select
框提供默认值。
尝试以下版本:
<select [(ngModel)]="'35'" (change)="leagueChoosen($event)">
<option></option>
<option *ngFor="let league of leagues.entries()" [value]="league[1]">{{league[0]}}
</option>
</select>
问题是您在 leagues.entries()
上循环,它在每次模板检查时重新运行,这发生在 (change) 回调之后。因此,选定的 DOM 元素将被替换,因为 entries
每次都会创建新对象。默认情况下,ngFor
使用对象引用来检查是否相等,由于重新创建了对象,因此它们不相等,因此重新创建了所选元素。
一个解决方法是确实在 <select>
上使用 [(ngModel)]
,但它没有解决问题的根源。
要使它更干净,您应该使用 trackBy
。
在你的组件 TS 代码中
// return the unique league key
trackLeagues(leagueEntry) { return leagueEntry[1] }
在模板中
*ngFor="let league of leagues.entries(); trackBy: trackLeagues"
这应确保所选 <option>
元素未被替换。
个人提示 - 我仍然认为最好使用 FormControl
并订阅其 valueChanges
。描述如何超出这个答案的范围。
给定以下组件 HTML:
<select (change)="leagueChoosen($event)">
<option disabled></option>
<option *ngFor="let league of leagues.entries()" value={{league[1]}}> {{league[0]} </option>
</select>
联赛所在位置:
leagues:Map<string,number> = new Map([["PORTUGAL 1", 35],["BELGIUM 1", 3], ["GERMANY 2", 18]])
所以,问题是,每当我 select 在我的下拉列表中手动选择一个项目时,后台逻辑是正确的 [函数 leagueChoosen() ] 正在正确地完成它的工作,但是,在那之后自动第一个项目列表中的(空白的)是 select 自动编辑的,因此下拉文本是空白的。
更新:(我也是 Angular 的新人) 有 3 个组件:sidebar、content、wrapper(前两个组件的父组件)
<!-- sidebar -->
<select (change)="leagueChoosen($event)">
<option></option>
<option *ngFor="let league of leagues.entries()" value={{league[1]}}>{{league[0]}}
</option>
</select>
<!-- content -->
<table>
<caption>Football<app-button (btnClick)="Delete()" text="Delete" float="right"></app-button></caption>
<thead>
<th style="text-align: left;">{{data[0]==undefined?"":data[0].liga_header}}</th>
<th colspan="3">Конечен тип</th>
<th colspan="3">Голови</th>
</thead>
<tbody>
<tr *ngFor="let match of data">
<td>{{match==undefined?"":match.broj}} - {{match==undefined?"":match.datum_vreme.substring(6,match.datum_vreme.length - 2) | date:"HH:mm"}} - {{match==undefined?"":match.tim1}} - {{match==undefined?"":match.tim2}}</td>
<td>{{match==undefined?"":match.k1}}</td>
<td>{{match==undefined?"":match.kx}}</td>
<td>{{match==undefined?"":match.k2}}</td>
<td>{{match==undefined?"":match.kgg3plus}}</td>
<td>{{match==undefined?"":match.k0do2}}</td>
<td>{{match==undefined?"":match.k3plus}}</td>
</tr>
</tbody>
<!-- wrapper -->
<div class='sidebar'>
<app-sidebar (liClick)="leagueChoosen($event)"></app-sidebar>
</div>
<div class='content'>
<ul>
<li *ngFor="let league of data"><app-content
(dlt)="Delete(league)"
[data]="league">
</app-content>
</li>
</ul>
</div>
问题似乎出在您的 html 中,您没有为 select
框提供默认值。
尝试以下版本:
<select [(ngModel)]="'35'" (change)="leagueChoosen($event)">
<option></option>
<option *ngFor="let league of leagues.entries()" [value]="league[1]">{{league[0]}}
</option>
</select>
问题是您在 leagues.entries()
上循环,它在每次模板检查时重新运行,这发生在 (change) 回调之后。因此,选定的 DOM 元素将被替换,因为 entries
每次都会创建新对象。默认情况下,ngFor
使用对象引用来检查是否相等,由于重新创建了对象,因此它们不相等,因此重新创建了所选元素。
一个解决方法是确实在 <select>
上使用 [(ngModel)]
,但它没有解决问题的根源。
要使它更干净,您应该使用 trackBy
。
在你的组件 TS 代码中
// return the unique league key
trackLeagues(leagueEntry) { return leagueEntry[1] }
在模板中
*ngFor="let league of leagues.entries(); trackBy: trackLeagues"
这应确保所选 <option>
元素未被替换。
个人提示 - 我仍然认为最好使用 FormControl
并订阅其 valueChanges
。描述如何超出这个答案的范围。