Единственное, что вам нужно, это использовать ссылочную переменную и посмотреть, является ли она действительной или нет.Я поместил простой пример в stackblitz .Поскольку вы хотите знать только, есть ли у вас действительный, вы можете использовать простой обязательный.Мой стек-блиц выглядит как
Обновление : в форме отключена кнопка отправки
@Component({
selector: 'my-app',
template: `
<div class="example-wrapper">
<form #myForm="ngForm">
<div *ngFor="let item of files; let i=index">
<p>T-shirt size:</p>
<kendo-dropdownlist name="select{{i}}" #name="ngModel" [(ngModel)]="value[i]" [data]="listItems" required>
</kendo-dropdownlist>
<span *ngIf="name.invalid">*</span>
</div>
<button [disabled]="myForm.invalid">submit</button>
</form>
</div>
`
})
export class AppComponent {
public listItems: Array<string> = ["X-Small", "Small", "Medium", "Large", "X-Large", "2X-Large"];
value=[]
files=[{value:''},{value:''},{value:''}]
}
Кратко объясните (но у вас есть документы )Когда у нас есть [(ngModel)], мы можем использовать ссылку на шаблон для ссылки на вход.Если мы сравним ссылку на шаблон с ngModel #name="ngModel"
, мы можем использовать в .html переменную шаблона и все свойства ngModel (недопустимый, тронутый ...) следующим образом: name.invalid
, name.touched
...
Ах !, не волнуйтесь, вы поставили «одну и ту же» ссылочную переменную, если переменная модели не равна, Angular понимает, что это разные переменные.
ПРИМЕЧАНИЕ:Лично я предлагаю вам использовать ReactiveForms и FormArray, но это всего лишь мнение
Обновление 2 Действительно Проблема в том, что вы не можете перебирать тот же список, который хотите изменить.У вас есть *ngFor="let item of files"
, и вы меняете files
.трюк заключается в итерации по ' '.repeat(files.length).split('')
или созданию массива в коде this.iterator=new Array(this.files.length)
, тогда вы можете сделать <tr *ngFor="let t of iterator;let i=index">
[(ngModel)] над файлами [i] .selectedDocumentItem.Id
См. stackblitz и код
<div class="example-wrapper">
<form #myForm="ngForm">
<!-- other way is <tr *ngFor="let t of iterator;let i=index"> -->
<tr *ngFor="let t of ' '.repeat(files.length).split(''); let i=index">
<td>
<kendo-dropdownlist name="select{{i}}" #name="ngModel" [(ngModel)]="files[i].selectedDocumentItem.Id" [defaultItem]="files[i].selectedDocumentItem.id"
[data]="DocumentTypes" [valuePrimitive]="true" textField="Name" valueField="Id" required>
</kendo-dropdownlist>
<span *ngIf="name.invalid">*</span>
</td>
</tr>
<button [disabled]="myForm.invalid">submit</button>
</form>
</div>
Если мы хотим использовать как [ngModel] = files [i] .selectedDocumentItem (объект), нам нужно создатьдиректива customError.Это выглядит как
@Directive({
selector: '[requiredId]',
providers: [{provide: NG_VALIDATORS, useExisting: RequiredIdDirective, multi: true}]
})
export class RequiredIdDirective implements Validator {
validate(control: AbstractControl): {[key: string]: any} | null {
return control.value.Id?null:{required:true}
}
}
И наше выпадающее меню теперь выглядит как
<kendo-dropdownlist name="select{{i}}" #name="ngModel"
[(ngModel)]="files[i].selectedDocumentItem"
[defaultItem]="files[i].selectedDocumentItem"
[data]="DocumentTypes"
textField="Name" valueField="Id" requiredId>
</kendo-dropdownlist>
Смотрите новый stackblitz