Angular2 下拉菜单恢复到以前选择的选项
Posted
技术标签:
【中文标题】Angular2 下拉菜单恢复到以前选择的选项【英文标题】:Angular2 Dropdown revert to previously selected option 【发布时间】:2018-03-03 15:12:43 【问题描述】:我有这个简单的 html 选择来实现 Angular2 (TS) 中的下拉菜单,如下所示
<select id="pageSize" (change)="onPageSizeChanged($event, pagination.pageSize)">
<option value="10">10</option>
<option value="20">20</option>
<option value="50">50</option>
</select>
之前选择的值保存在pagination.pageSize
变量中。在改变这一点时,我想打开一个对话框并等待用户响应。如果用户单击取消,我想将选择恢复为先前选择的选项。
onPageSizeChanged(event, oldValue)
const response = window.confirm("Are you sure you want change the page size? Your edits will be lost?");
if (response)
//... some code ...
else
//... here I want to revert the selection to previously selected option
尝试了很多不同的东西,但都没有成功。
请帮忙,我正在为这个简单的事情失去理智。我一定是在做傻事。
尝试 #1 - 无效 (Plunk - https://embed.plnkr.co/ILi12O/)
<select id="pageSize" [ngModel]="pageSize" (ngModelChange)="onPageSizeChanged($event, pagination.pageSize)">
<option value="10">10</option>
<option value="20">20</option>
<option value="50">50</option>
</select>
onPageSizeChanged(event, oldValue)
const response = window.confirm("Are you sure you want change the page size? Your edits will be lost?");
if (response) //go ahead so something
else this.pageSize = oldValue;
【问题讨论】:
使用 ngModel 并设置反映所选值的 ngModel 不走运。试过以下<select id="pageSize" [ngModel]="pageSize" (ngModelChange)="onPageSizeChanged($event, pagination.pageSize)"> <option value="10">10</option> <option value="20">20</option> <option value="50">50</option> </select>
onPageSizeChanged(event, oldValue) const response = window.confirm("Are you sure you want change the page size? Your edits will be lost?"); if (response) //go ahead so something else this.pageSize = oldValue;
你能用变化更新代码吗
【参考方案1】:
添加ngModelChange
以跟踪模型更改。如果对话框确认下一次更改,则保留更改,否则设置回值。本地模板变量 (#select) 使跟踪更容易一些。我根据您的 plunker 进行了更改:
HTML:
<select #select id="pageSize" [ngModel]="pageSize" (ngModelChange)="select.value = onPageSizeChanged($event)">
TypeScript:
onPageSizeChanged(event)
const response = window.confirm("Are you sure you want change the page size? Your edits will be lost?");
console.log(this.pagination.pageSize)
if (response)
this.pageSize = event;
this.pagination.pageSize = event;
else
this.pageSize = this.pagination.pageSize;
return this.pagination.pageSize;
demo
【讨论】:
一个限制似乎是,如果您有一个 async (promise, rxjs) 方法调用,则无法在表达式中使用 .then 或 .subscribe 或使用异步管道来处理返回值。在方法上使用异步管道会收到错误“动作表达式中不能有管道”。使用 .then 或 .subscribe 会导致表达式解析错误)。由于在 formControl 更新后调用了 ngModelChange,这可能在 6+ 中有效。【参考方案2】:https://plnkr.co/edit/RR8XgZW2KIcYTnxo7Iju?p=preview
您可以在您的 component.html 文件中执行类似的操作...
在您的选择元素上添加template reference variable#pageSize
然后(更改),将该变量的值(pageSize.value)设置为等于我们接下来将创建的 onChangeSize 方法。将 pageSize.value 传递给这个 onChangeSize 方法,如下所示: (change) = "pageSize.value = onChangeSize(pageSize.value)
这给了我们...
<select id="pageSize" #pageSize
(change)="pageSize.value = onChangeSize(pageSize.value)">
<option value="10">10</option>
<option value="20">20</option>
<option value="50">50</option>
</select>
并在您的 component.ts 文件中,创建一个采用该值的方法,如果用户确认更改,我们只需立即返回该值。如果用户拒绝更改,我们将返回默认值。
export class MathComponent implements OnInit
defaultInput: number = 10;
userInput: number = this.defaultInput;
constructor()
ngOnInit()
onChangeSize(pageSize: HTMLSelectElement)
const response = window.confirm("Are you sure you want change the page size? Your edits will be lost?");
if (response)
return pageSize;
else
return this.defaultInput;
https://plnkr.co/edit/RR8XgZW2KIcYTnxo7Iju?p=preview
【讨论】:
【参考方案3】:对于 (ngModelChange)
方法包含异步代码(async/await、Promise、rxjs Observable)的 Select 控件,Angular 6 之前的代码可以使用以下解决方案。
<select
id=" user.emailAddress "
class="form-control role-select"
aria-label="Dropdown"
[disabled]="busy"
[(ngModel)]="user.role"
(ngModelChange)="editUserRole(user)"
>
<option *ngFor="let role of (roles | async)" [value]="role">
role
</option>
</select>
在控制器中
public async editUserRole(user: IUser)
if (user.role === SubscriptionUserRole.DATA_DEFAULT && !this._hasAtLeastOneOtherAdmin(user))
// Execute on the next app.tick cycle. Pre V6, the HTML Element value is not updated until after ngModelChange.
// This may not be needed in Angular V6.
// zone.js and ngZone intercept async operations to trigger UI updates. Hence, no need to call app.tick.
setTimeout(() =>
user.role = SubscriptionUserRole.DATA_ADMIN;
, 0);
this.errorMessage = 'At least one user should be DataAdmin';
return;
// Continue change operation like database update here.
我想在某些情况下,延迟更新可能会造成问题。
由于在 ngModelChangeCall 之前更新 FormControl 的变化,在 Angular 6+ 中可能不需要此延迟。
【讨论】:
以上是关于Angular2 下拉菜单恢复到以前选择的选项的主要内容,如果未能解决你的问题,请参考以下文章
Angular 2 选择选项(下拉菜单) - 如何获取更改值以便可以在函数中使用?