Angular7 Mat-select intercept change

不打扰是莪最后的温柔 提交于 2020-06-13 06:31:10

问题


In my use case scenario I have a dropdown box (mat-select) which fills several input fields. Any change will fill the fields differently. Since the user could change a field I want to ask the user before the final change is executed if (s)he agree to clear(or change) all fields. In case of a NO the selection change will not happen and all fields should remain.

I tried to reduce the use case to a sample. I can select an item from the dropdown and do some further actions.

  <mat-select (selectionChange)="intercept($event.value)">
    <mat-option *ngFor="let food of foods" [value]="food.value" >
      {{food.viewValue}}
    </mat-option>
  </mat-select>

But at the time the selectionchange is exectued the content of the dropdown is already changed. For the sample I would like to have e.g.

  1. Select e.g. Pizza
  2. Popup appears
  3. !The dropdown remains on the original selection and after the popup disappears a change happen!
  4. Select e.g. Tacos
  5. Popup appears
  6. !The dropdown remains on the original selection (=Tacos) and after the popup disappears a change happen!

I have no clue how to intercept the change event before the change happen.


回答1:


Far as I know, you cant prevent this change. The only possibility is to save the old value of the selection and reset it to this value if the user cancels the modal/popup. I had the same problem a while ago.

Edit: Maybe this could help Thread




回答2:


We can't intercept the select change event before the change happens, because the selectionChange event is :

Event emitted when the selected value has been changed by the user.

, as described in Angular Material docs.

But we can trigger the update of the other form controls only after the user confirms it.

And, as @liqSTAR described, we must save the previous value of the selection and reset the select to it if the user cancels the popup.

A simple example would be:

<mat-select [(ngModel)]="selectedFood" (selectionChange)="intercept($event.value)">
selectedFood = '';
previousSelectedFood = '';


intercept(food:any) {
  const bottomSheetRef = this.bottomSheet.open(BottomSheetOverviewExampleSheet);

  bottomSheetRef.afterDismissed().subscribe( result => {
    if (result === true) {
       // update the the previous selected value
       this.previousSelectedFood = food;

       // update the other inputs based on `food` value
       this.otherInputValues = food;

    } else {
       // reset the selection to the previous value
       this.selectedFood = this.previousSelectedFood;
    }
  });
}

Demo: https://stackblitz.com/edit/angular-dhgfmx-9rzt7v

Now, the example above has an issue:

  • in UI, the select displays the new selected value, when the popup is opened, even if the user has not made a decision :

In order to fix this issue, we have to reset the selected value to its previous value immediately after the selectionChange event fires, that let the user decide, and if it confirms the selectios, we'll update update the select accordingly.

The code would be:

intercept(food:any) {

  // at first, reset the select to the previous value
  // so that the user could not see that the select has really changed
  // we need a timeout to make in work
  setTimeout( () => {
    this.selectedFood = this.previousSelectedFood;
  }, 1);

  const bottomSheetRef = this.bottomSheet.open(BottomSheetOverviewExampleSheet);

  bottomSheetRef.afterDismissed().subscribe( result => {
    if (result === true) {
       // update the selected value
       this.selectedFood = food;

       // update the previous selected value
       this.previousSelectedFood = food;

       // update the other inputs based on `food` value
       this.otherInputValues = food;
    }
  });
}

Demo: https://stackblitz.com/edit/angular-dhgfmx-xmvfvf




回答3:


Here's what i do.

template:

<mat-select [ngModel]="something"
            (ngModelChange)="changeSomething($event, ngModelControl)"
            #ngModelControl="ngModel">
   ...
</mat-select>

code:

changeSomething(value: any, ngModelControl: NgModel) {
  if (<<false for whatever reason>>) {
    // reset mat-select
    ngModelControl.control.setValue(this.something);
  } else {
    this.something = value;
  }
}


来源:https://stackoverflow.com/questions/56269995/angular7-mat-select-intercept-change

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