Angular2 Dropdown revert to previously selected option

折月煮酒 提交于 2019-11-30 09:19:49

问题


I have this simple HTML select to implement dropdown in Angular2 (TS) as shown below

<select id="pageSize" (change)="onPageSizeChanged($event, pagination.pageSize)">
  <option value="10">10</option>
  <option value="20">20</option>
  <option value="50">50</option>
</select>

The previously selected value is kept in pagination.pageSize variable. And on change of this I wanted to open a dialog box and wait for users response. If user, clicks cancel I want to revert the selection to the previously selected options.

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
  }
}

Tried lot of different things but of no luck.

Please help, I am loosing my mind over this simple thing. I must be doing something stupid.


Tries #1 - Didn't work (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; }  
} 

回答1:


Try the following. Add ngModelChange method to track the model changes. Keep the change if the dialog confirms and keep the value for the next change, otherwise set back the value. Local template variable (#select) make a little easier to track. I made changes based on your 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;
  } 

plunker




回答2:


https://plnkr.co/edit/RR8XgZW2KIcYTnxo7Iju?p=preview

You could do something like this in your component.html file...

Add a template reference variable #pageSize on your select element

and on (change), set the value of that variable (pageSize.value) equal to your onChangeSize method that we'll create next. Pass the pageSize.value to this onChangeSize method like this: (change) = "pageSize.value = onChangeSize(pageSize.value)

this gives us...

<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>    

and in your component.ts file, create a method which takes that value & if the user confirms the change, we simply return that value right back. If the user rejects the change, we return the default value instead.

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:


For Select controls whose (ngModelChange) method includes asynchronous code (async/await, Promise, rxjs Observable), pre Angular 6 code may use the following solution.

      <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>

In the contorller

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.
}

I suppose that in some scenarios the delayed updated could pose a problem.

This delay may not be necessary in Angular 6+ due to the change where the FormControl is updated prior to the ngModelChangeCall.



来源:https://stackoverflow.com/questions/46357952/angular2-dropdown-revert-to-previously-selected-option

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!