установите поле выбора недействительным вручную в Angular 8 - PullRequest
0 голосов
/ 05 февраля 2020

У меня есть поле выбора в Angular 8, которое связано с кнопкой. Я хочу иметь возможность нажимать на кнопку, и если в поле ничего не выбрано, я хочу сделать поле недействительным.

Вот мое поле выбора и кнопка:

<div class="input-group-prepend">
       <button class="btn btn-primary" type="button" (click)="AddNewSchedule()>
          <i class="material-icons post_add" aria-hidden="true"></i>
       </button>
    </div>
    <select class="form-control"
      [(ngModel)]="ScheduleDataObj.modeOfTransportID"
      name="modeOfTransportID"
      #modeOfTransportID="ngModel"
      (change)="ModeValueChange($event)"
    >
      <option [value]="0">Select Mode</option>
      <option *ngFor="let m of Modes" [value]="m.modeOfTransportID">{{ m.mode }}</option>
    </select>

Как сделать поле недействительным вручную?

Это то, что я пробовал использовать функцию обработчика событий, связанную с кнопкой:

@ViewChild('modeOfTransportID', { static: false }) modeID: HTMLFormElement;

public AddNewSchedule() {
 if (this.ScheduleDataObj.modeOfTransportID === 0) {
      this.modeID.setErrors({ invalid: true });
      return false;
    } else {
      this.modeID.setErrors(null);
   } 
}

При нажатии кнопки я получаю сообщение об ошибке «setErrors не является функцией». Я также попытался сделать this.modeID.control.invalid = true, который не работал.

Ответы [ 2 ]

2 голосов
/ 05 февраля 2020

Это должен быть тип директивы NgModel, а не HTMLFormElement и метод setError, доступный внутри свойства элемента управления

Попробуйте это:

   @ViewChild('modeOfTransportID', { static: false }) modeID: NgModel;
   public AddNewSchedule() {
    if (this.ScheduleDataObj.modeOfTransportID === 0) {
      this.modeID.control.setErrors({ invalid: true });
      return false;
    } else {
      this.modeID.control.setErrors(null);
    } 
  }
0 голосов
/ 05 февраля 2020

@ Ответ Челлаппана совершенно верен, но есть несколько других проблем с вашим кодом, которые я хотел бы решить. Во-первых, в расчете на c, value всегда будет иметь тип string. Таким образом, this.ScheduleDataObj.modeOfTransportID === 0 всегда будет ложным, потому что оно должно быть === '0'. Однако вы можете исправить это, используя ngValue . Из документов (выделено мое):

ngValue: отслеживает значение, связанное с элементом option. В отличие от привязки значения, ngValue поддерживает привязку к объектам.

Таким образом, вы можете реорганизовать ваше представление для использования ngValue, и ваш код будет работать:

<select class="form-control"
  [(ngModel)]="ScheduleDataObj.modeOfTransportID"
  name="modeOfTransportID"
  #modeOfTransportID="ngModel"
  (change)="ModeValueChange($event)">
  <option [ngValue]="0">Select Mode</option>
  <option [ngValue]="1">Some Mode</option>
</select>

Кроме того, вместо того, чтобы думать о просмотре значения в терминах событий html (что может оказаться непростым делом, поскольку значение вашей модели может измениться не совсем точно, если вы думаете, что это так), вы можете реорганизовать код для просмотра FormControl сам для изменения стоимости. Обязательно дождитесь окончания инициализации представления, чтобы ваш @ViewChild ref не был нулевым:

ngAfterViewInit() {
  // Watch our modeID value changes.
  // Using takeUntil to avoid memory leaks.
  this.modeID.valueChanges
    .pipe(takeUntil(this.unsubscribe))
    .subscribe(value => {
      if (value === 0) {
        // Note: this will remove other validation errors. 
        // If that is not desired behavior, see this discussion:
        // https://github.com/angular/angular/issues/21564
        this.modeID.control.setErrors({ invalid: true });
      } else {
        // This also removes *all* errors, which might not
        // be desired behavior.
        this.modeID.control.setErrors(null);
      }
    });
}

Собрав все вместе, вот рабочий пример работы над stackblitz . Вы также можете просто создать собственный валидатор для этого.

...