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 不走运。试过以下&lt;select id="pageSize" [ngModel]="pageSize" (ngModelChange)="onPageSizeChanged($event, pagination.pageSize)"&gt; &lt;option value="10"&gt;10&lt;/option&gt; &lt;option value="20"&gt;20&lt;/option&gt; &lt;option value="50"&gt;50&lt;/option&gt; &lt;/select&gt;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 选择选项(下拉菜单) - 如何获取更改值以便可以在函数中使用?

Angular2/PrimeNG - 无法显示下拉菜单

为啥网页下拉菜单弹不出来

禁用先前选择的下拉选项,检查文本和 id 值

React - 需要下拉菜单来选择正确的选项(下拉菜单的选项值表示为字符串数字)

jquery在下拉菜单中找到所选项目的值