Angular 5:如何对两个具有相同数据的下拉列表设置验证?
Angular 5 : How to set Validation on two drop down list having same data?
数据(json)
{
"time": [
"2017-1",
"2017-2",
"2017-3",
"2017-4",
"2017-5",
....
]
}
模板(Angular Material)
<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>
我有两个下拉列表包含具有多个 selection 的相同数据,如果我在 2017-1、2017-2(第一个下拉列表)上 select 那么这个值应该不是 selected/populated 在第二个下拉列表中。我是 angular/Material 的初学者,我应该在此处进行验证!我不知道我应该在 HTML/Type-Script 中写什么逻辑。
提前致谢
有几种方法可以做到这一点...例如,只有一种方法是将数组分成两部分,然后在第一个选项中 selected 时拼接第二个数组的值mat-select
.
- 您也可以只禁用第二个列表中的选项
select 在第一个
mat-select
编辑...这将是我的场景
将在本示例中使用。
创建组件变量以存储来自第一个 mat-select
的 select 离子
firstSelections: string = '';
创建方法以在该变量内设置第一个 selection 值
setFirstValues(values) {
this.firstSelections = values;
}
然后在第一个 mat-select
的 selection 变化上调用该方法并传递值。
<mat-select #select1 placeholder="Select Year/Week" class="DropDownYear" multiple (selectionChange)="setFirstValues($event.value)">
然后在你的第二个 mat-select
定义选项时使用 属性 绑定 disabled
来检查选项是否包含在变量 firstSelections
中以禁用第二个选项列出如果 selected 在第一个。
<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
如果您需要从第二个列表中物理删除选项,您将需要探索将每个 mat-select... 拆分 resYearData
到两个单独的数组中,然后删除值来自第一个 mat-select
.
的 selection 上的第二个数组
- 概念相同,但不是分配 selection
到禁用比较的变量,你只需删除
setFirstValues()
方法中第二个数组的值。
根据 malbarmawi 在下面的评论
我已经修改了 stackblitz 以解决如果有人首先从第二个列表中 selects 的问题,方法是从第二个列表中删除 selection 然后禁用。
将 html 包装在模板驱动的表单中,您可以随意命名它,在本例中我只是将其命名为 myForm
<form #myForm="ngForm">
在 selectionChange
上将表单传递给您的方法
(selectionChange)="setFirstValues(myForm)"
为每个 mat-selects
分配名称和 ngModel
name="select1" ngModel
通过 ViewChild
获取对第二个 select 的引用
@ViewChild('select2') _select2: any
设置第一个 selection 值更改和拼接来自第二个列表的值(如果存在)和 deselect.
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);
}
}
}
}
我确实建议使用反应式表单验证 (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
function is the validation login for the dropdown values
模板
<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}}
数据(json)
{
"time": [
"2017-1",
"2017-2",
"2017-3",
"2017-4",
"2017-5",
....
]
}
模板(Angular Material)
<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>
我有两个下拉列表包含具有多个 selection 的相同数据,如果我在 2017-1、2017-2(第一个下拉列表)上 select 那么这个值应该不是 selected/populated 在第二个下拉列表中。我是 angular/Material 的初学者,我应该在此处进行验证!我不知道我应该在 HTML/Type-Script 中写什么逻辑。 提前致谢
有几种方法可以做到这一点...例如,只有一种方法是将数组分成两部分,然后在第一个选项中 selected 时拼接第二个数组的值mat-select
.
- 您也可以只禁用第二个列表中的选项
select 在第一个
mat-select
编辑...这将是我的场景 将在本示例中使用。
创建组件变量以存储来自第一个 mat-select
firstSelections: string = '';
创建方法以在该变量内设置第一个 selection 值
setFirstValues(values) {
this.firstSelections = values;
}
然后在第一个 mat-select
的 selection 变化上调用该方法并传递值。
<mat-select #select1 placeholder="Select Year/Week" class="DropDownYear" multiple (selectionChange)="setFirstValues($event.value)">
然后在你的第二个 mat-select
定义选项时使用 属性 绑定 disabled
来检查选项是否包含在变量 firstSelections
中以禁用第二个选项列出如果 selected 在第一个。
<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
如果您需要从第二个列表中物理删除选项,您将需要探索将每个 mat-select... 拆分 resYearData
到两个单独的数组中,然后删除值来自第一个 mat-select
.
- 概念相同,但不是分配 selection
到禁用比较的变量,你只需删除
setFirstValues()
方法中第二个数组的值。
根据 malbarmawi 在下面的评论
我已经修改了 stackblitz 以解决如果有人首先从第二个列表中 selects 的问题,方法是从第二个列表中删除 selection 然后禁用。
将 html 包装在模板驱动的表单中,您可以随意命名它,在本例中我只是将其命名为 myForm
<form #myForm="ngForm">
在 selectionChange
(selectionChange)="setFirstValues(myForm)"
为每个 mat-selects
name="select1" ngModel
通过 ViewChild
@ViewChild('select2') _select2: any
设置第一个 selection 值更改和拼接来自第二个列表的值(如果存在)和 deselect.
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);
}
}
}
}
我确实建议使用反应式表单验证 (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
function is the validation login for the dropdown values
模板
<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}}