Angular 5: Как установить валидацию в двух выпадающих списках с одинаковыми данными? - PullRequest
0 голосов
/ 29 ноября 2018

Данные (json)

{
  "time": [
    "2017-1",
    "2017-2",
    "2017-3",
    "2017-4",
    "2017-5",
    ....
  ]
}

Шаблон (угловой материал)

<mat-tab label="Recomandation Setting">
      <div class="row">
        <div class="col-md-4">
          <mat-form-field>
            <mat-select placeholder="Select Year/Week" class="DropDownYear" multiple>
              <mat-option *ngFor="let time1 of resYearData.time" [value]="time1">{{time1}}</mat-option>
            </mat-select>
          </mat-form-field>
        </div>
      </div>
      <div class="row">
        <div class="col-md-4">
          <mat-form-field>
            <mat-select placeholder="Select Year/Week" class="DropDownYear" multiple>
              <mat-option *ngFor="let time2 of resYearData.time" [value]="time2">{{time2}}</mat-option>
            </mat-select>
          </mat-form-field>
          <button mat-raised-button color="primary" (click)='toggle()'>View</button>
        </div>
      </div>
</mat-tab>

У меня есть два Раскрывающийся список содержит те же данные с множественным выбором, если я выберу 2017-1, 2017-2 (первое раскрывающееся меню), тогда это значение не должно быть выбрано / заполнено во втором раскрывающемся списке.Я новичок в угловой / Материал, что я должен поставить здесь проверку!Я не знаю, какую логику мне написать в HTML / Type-Script. заранее спасибо

Ответы [ 2 ]

0 голосов
/ 29 ноября 2018

Я рекомендую использовать реактивную проверку формы (FormGroup), так как она более чистая, и вы получаете brnifetate для отображения ошибки проверки, отключите кнопку сохранения на основе проверки формы

Компонент

 form: FormGroup;
  constructor(fb: FormBuilder) {
    let dropDownValueValidation = function (frm: FormGroup) {
      const firstValue: string[] = frm.get('first').value || [];
      const secondValue: string[] = frm.get('second').value || [];
      if (secondValue.length > 0 && firstValue.length > 0) {
        if (secondValue.some(v => firstValue.indexOf(v) !== -1)) {
          return { 'invalid': 'you can\'t use first element selection' }
        }
      } else {
        return null;
      }
    }

    this.form = fb.group({
      first: [],
      second: []
    }, { validator: dropDownValueValidation })
  }


  logValues() {
    console.log(this.form.value)
  }

dropDownValueValidation - это логин для проверки выпадающих значений

Шаблон

<div [formGroup]="form">
<mat-form-field>
    <mat-select formControlName="first" placeholder="Select Year/Week" class="DropDownYear" multiple >
        <mat-option *ngFor="let time1 of resYearData.time" [value]="time1">{{time1}}</mat-option>
    </mat-select>
</mat-form-field>

<div class="col-md-4">
    <mat-form-field>
        <mat-select formControlName="second" placeholder="Select Year/Week" class="DropDownYear" multiple>
            <mat-option *ngFor="let time2 of resYearData.time" [value]="time2" >{{time2}}</mat-option>
        </mat-select>
    </mat-form-field>
</div>
<button mat-raised-button color="primary" [disabled]="form.invalid" (click)='logValues()'>View</button>
</div>
<br>
Form Validation => {{form.errors | json}}

демонстрация стекаблиц

0 голосов
/ 29 ноября 2018

Есть несколько способов сделать это ... например, одним из способов было бы разделить массивы на два и разделить значения из второго массива, когда в первом mat-select.

выбрана опция.
  • Вы также можете просто отключить параметры во втором списке при выборе в первом mat-select ... это будет сценарий, который я буду использовать в этом примере.

Создатьпеременная компонента для хранения выборок из первых mat-select

firstSelections: string = '';

Создать метод для установки первых значений выбора внутри этой переменной

setFirstValues(values) {
    this.firstSelections = values;
  }

Затем вызвать этот метод при изменении выбора из первой mat-select и передайте значения.

<mat-select #select1 placeholder="Select Year/Week" class="DropDownYear" multiple (selectionChange)="setFirstValues($event.value)">

Затем во втором mat-select при определении параметров используйте привязку свойства к disabled, чтобы проверить, включена ли опция в переменную firstSelections, чтобы отключить эту опцию во второмсписок, если выбран в первом.

<mat-option *ngFor="let time2 of resYearData.time" [value]="time2" [disabled]="firstSelections.includes(time2)">{{time2}}</mat-option>

Stackblitz

https://stackblitz.com/edit/angular-rc5vwq?embed=1&file=app/select-overview-example.html


Если вам требуется физическое удаление опцийот Во втором списке вам нужно изучить разбиение resYearData на два отдельных массива для каждого выбора mat ... и затем удалить значения из второго массива при выборе первого mat-select.

  • Концепция будет такой же, но вместо того, чтобы назначать выбор переменной для сравнения при отключении, вы просто удалите значения из второго массива в методе setFirstValues().

В соответствии с комментарием, сделанным ниже malbarmawi

Я исправил стек-блиц, чтобы устранить проблему, если кто-то сначала выбирает второй список, удаляя выбор из второго списка, а затем отключая.

Оберните HTML в шаблонно-управляемую форму, вы можете называть его как угодно, в этом примере я просто называю это myForm

<form #myForm="ngForm">

Передайте форму вашему методу на selectionChange

(selectionChange)="setFirstValues(myForm)"

Назначение имени и ngModel для каждого из mat-selects

name="select1" ngModel

Получение ссылки на второй выбор с помощью ViewChild

@ViewChild('select2') _select2: any

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

setFirstValues(form) {
    this.firstSelections = form.value.select1
    const secondSelectionsValues = this._select2.value.slice();
    for (var i = 0; i < secondSelectionsValues.length; i++) {
      if (this.firstSelections.includes(secondSelectionsValues[i])) {
        secondSelectionsValues.splice(i, 1)
        this._select2.writeValue(secondSelectionsValues);
      }
    }
  }

Редакция

Добавить проверку на ноль, чтобы предотвратить запуск логики, если this._select2.value нет.

setFirstValues(form) {
    this.firstSelections = form.value.select1
    if (this._select2.value) {
      const secondSelectionsValues = this._select2.value.slice();
      for (var i = secondSelectionsValues.length - 1; i >= 0; i--) {
        if (this.firstSelections.includes(secondSelectionsValues[i])) {
          secondSelectionsValues.splice(i, 1)
          this._select2.writeValue(secondSelectionsValues);
        }
      }
    }
  }
...