2016-06-11 2 views
3

У меня есть элемент формы, в котором я могу добавить и удалить значение динамически.Проверка формы для динамически добавленной и удаленной формы Элементы

Например, в следующей кодовой области могут быть добавлены и удалены с помощью addDomain и removeDomain

<div *ngFor="let item of company.domains"> 
        <div class="row"> 
         <div class="col-lg-9"> 
          <input type="text" class="form-control" ngControl="domainC" [(ngModel)]="company.domains[i]"> 
         </div> 
         <div class="col-lg-3 pull-left"> 
          <a (click)="removeDomain(i)"> <i class="fa fa-times"></i></a> 
          <a (click)="addDomain()"> <i class="fa fa-plus"></i></a> 
         </div> 
        </div> 
       </div> 

Мне нужно, чтобы проверить их на представить, так как все добавленные значения необходимы. Я работаю с Control в угловом 2, но не могу понять, как применить валидацию к таким элементам. Любая помощь будет оценена.

ответ

2

Plunker example

Вы можете связать форму с формой модели

<form [ngFormModel]="form"> 
    <div *ngFor="let item of controls let idx=index"> 
    <div class="row"> 
     <div class="col-lg-9"> 
     <label>{{item.name}}</label><input type="text" class="form-control" [ngControl]="item.name" [(ngModel)]="values[item.name]"> 
     {{item.control.errors | json}} 
     </div> 
     <div class="col-lg-3 pull-left"> 
     <div><button (click)="removeDomain(i)">remove</button></div> 
     </div> 
    </div> 
</div> 

<hr> 

<div> 
    <label>control name</label><input #nameInput> 
    <label>validator</label><select #validatorInput> 
    <option>required</option> 
    <option>minLength</option> 
    <option>maxLength</option> 
    </select> 
    <label>length</label><input type="number" #lengthInput> 
    <button (click)="addDomain(nameInput.value, validatorInput.value, lengthInput.value)">add</button> 
</div> 

export class App { 
    form:ControlGroup; 
    controls [ 
    { name: 'name', control: new Control('', Validators.required) }, 
    { name: 'password', control: new Control('', Validators.minLength(3))} 
    ]; 
    values = { 
    name: '', 
    password: '', 
    } 

    constructor(fb:FormBuilder) { 
    this.form = fb.group(); 
    this.name = 'Angular2 (Release Candidate!)' 
    this.controls.map((item) => { 
     console.log('map item', item); 
     this.form.addControl(item.name, item.control); 
    }); 
    } 

    removeDomain(i) { 
    this.values[this.controls[i].name]=undefined; 
    this.form.removeControl(this.controls[i].name); 
    this.controls.splice(i); 
    this.form.controls.forEach(c => c.updateValueAndValidity()); 
    } 

    addDomain(name, validator, length) { 
    this.values[name] = ''; 
    var validator; 
    if(length) { 
     validator = Validators[validator](length); 
    } else { 
     validator = Validators[validator]; 
    } 

    let newCtl = new Control('', validator); 
    this.controls.push({name: name, control: newCtl}); 
    this.form.addControl(name, newCtl); 
    //this.controls.forEach(c => this.form.controls[c.name].updateValueAndValidity()); 
    } 
} 
+1

Благодарим вас за помощь :) – 4rpit

0

Если вы хотите выполнить проверку программно в контроллере представления, можно ссылаться ваш контроль в вашем представлении и передать его контроллеру при изменении. Что-то вроде:

<input type="text" class="form-control" ngControl="domainC" #domainCControl="ngForm" [(ngModel)]="company.domains[i]" (change)="onDomainInputChanged(domainCControl)"> 
<div [hidden]="domainCControl.valid">Control invalid</div> 

контроллер:

onDomainInputChanged(control: NgControlName) { 
    // You have access to control.control.validatorFn here 
} 

Но вы, вероятно, хотите реализовать валидатор в специальной директиве можно повторно использовать в других местах:

<input type="text" class="form-control" ngControl="domainC" [(ngModel)]="company.domains[i]" validate-domain-control > 

И директиву:

@Directive({ 
    selector: '[validate-domain-control][ngControl],[validate-domain-control][ngModel],[validate-domain-control][ngFormControl]', 
    providers: [{provide: NG_VALIDATORS, useExisting: forwardRef(()=>DomainValidator), multi: true}] 
}) 
export class DomainValidator implements Validator { 

    constructor() {} 

    validate(control:AbstractControl) { 
     if (isValid(control.value)) { 
      return null; 
     } 
     return {'myValidityClass': false}; 
    } 
} 
+0

Вы также можете использовать атрибуты проверки html, такие как 'required',' min-length = "3" 'и т. Д. ... которые уже обрабатываются угловыми. – cghislai

1

Я нашел решение. Проблема была связана с присвоением имени элемента управления. Когда строка была удалена с середины, индекс таблицы будет восстановлен и добавлен еще одна строка с дублирующимся именем управления.

Plunker link

Добавлен счетчик, который всегда увеличивает и назначили его детализации объекта.

addRow() { 
    this.details.push(<IDetail>{controlIndex:this.iRow}); 

    this.rowValidateForm(this.iRow++, 'add');   
} 

On remove get counter from detail object и удалить элементы управления из группы с именем счетчика.

removeRow(index) { 
    let controlIndex = this.details[index].controlIndex; 

    this.details.splice(index, 1); 
    this.rowValidateForm(controlIndex, 'remove'); 
} 

В поле зрения заменить индекс строки в FormControlName с помощью countrolIndex.

Смежные вопросы