角5:如何在具有相同数据的两个下拉列表上设置验证?

时间:2018-11-29 14:26:00

标签: angular angular-material angular5

数据(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 :(得分:2)

有多种方法可以完成此操作...例如,只有一种方法是在第一个mat-select中选择一个选项时,将数组拆分为两个并从第二个数组中拼接值。 / p>

  • 您还可以在以下情况下禁用第二个列表中的选项: 在第一个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-select的两个单独的数组...,然后在选择时从第二个数组中删除值前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);
        }
      }
    }
  }

答案 1 :(得分:2)

我建议您使用反应性表单验证(FormGroup),它更干净,并且您会看到显示错误的简短提示,并基于表单验证禁用保存按钮

组件

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

stackblitz demo