简体   繁体   中英

Cannot set selected item value using ngModel in angular7 ng-select

I am using angular7 ng-select library to implement a select control. I am using Angular CLI for development. I am trying to prevent event propagation when a change event is triggered. I found out that the change event propagation cannot be prevented in this case. The way around it would be to set the selected value programmatically.

So, I have a [(ngModel)]="selectedOption" property set in my ng-select control. In my typescript file, in the function triggered by the change event, I set the previously selected value to prevent any change in the selected option. But this value is not reflected in the ng-select control. I also tried detecting changes using ChangeDetectorRef.

ng-select HTML:

 <ng-select [items]="selectOptions" bindValue="value"
    [(ngModel)]="selectedOption" (change)="onChangeOption($event)">
    <ng-template ng-label-tmp let-item="item">
    <img [src]="item.iconOption" /> {{ item.text }}
    </ng-template>
    <ng-template ng-option-tmp let-item="item">
    <img [src]="item.iconOption" class="pr-3" />{{ item.text }}
    </ng-template>
</ng-select>

Complete ts file code:

export class SampleComponent implements OnInit, OnChanges {

  @Input() reportStatus: string;
  selectOptions: any[];
  selectedOption: string;
  previousSelectedOption: string;

  constructor() {}

  ngOnInit() {
    this.selectedOption = this.reportStatus;
    this.previousSelectedOption = this.reportStatus;
    this.selectOptions = [
      {
        id: '1',
        value: 'draft',
        iconOption: '../../../assets/images/Draft.svg',
        text: 'Draft'
      },
      {
        id: '2',
        value: 'approved',
        iconOption: '../../../assets/images/Approved.svg',
        text: 'Approved'
      },
      {
        id: '3',
        value: 'completed',
        iconOption: '../../../assets/images/Completed.svg',
        text: 'Completed'
      },
      {
        id: '4',
        value: 'cancelled',
        iconOption: '../../../assets/images/Cancelled.svg',
        text: 'Cancelled'
      }
    ];
  }

  onChangeOption(event) {
    // cannot change status if current status is completed
    // reset to previous selected value
    if (this.previousSelectedOption === 'completed') {
      this.selectedOption = this.previousSelectedOption;
      return;
    }
    this.previousSelectedOption = event.value;
  }
}

I am expecting the selected value in the ng-select control to be reset to the previous value. But the new changed value is set irrespectively.

I tried the accepted solution from here: set selected value in angular5 ng-select programmaticaly

But I want to know if there is a simpler approach to this. Also, I have multiple ng-select controls in my page so using ViewChild would be a hassle.

  onChangeOption(event) {
    setTimeout(() => {
      if (this.previousSelectedOption === 'completed') {
        this.selectedOption = this.previousSelectedOption;
        return;
      }
    });
    this.previousSelectedOption = event.value;
  }

You can achieve the expected behavior by adding a timeout.

The reason for not updating the selected value after changing the ngmodel is during onChange it is already updating the ngmodel with the selected value and once you reset it back it won't appear in the UI since it has happened in the same change detection cycle.

By using setTimeOut it will see the new changes done to the ngmodel and apply it in the next change detection cycle.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM