在指令中具有HostListener的FormArray

时间:2018-06-30 09:10:45

标签: angular typescript

我正在循环中创建输入表单:

  <tr formArrayName="items" *ngFor="let vatCat of items.controls; let i = index">
            <td [formGroupName]="i">
              <input name="symbol" minlength="1" maxlength="1" [(ngModel)]="symbol" appUppercase type="text" formControlName="symbol">
            </td>
            <td [formGroupName]="i">
              <input name="value"  type="number" [ngModel]="0" formControlName="value">
            </td>
            <td [formGroupName]="i">
              <span class="table-remove">
                <button (click)="removeItem(i)" type="submit" class="btn btn-danger btn-rounded btn-sm my-0">Usuń</button>
              </span>
            </td>
....

然后我必须将符号输入中的每个值都更改为大写,因此我创建了一条指令:

@Directive({
  selector: '[ngModel][appUppercase]'
})
export class UppercaseDirective {
  @Output() ngModelChange: EventEmitter<any> = new EventEmitter();
  value: any;

  @HostListener('input', ['$event']) onInputChange($event) {
    this.value = $event.target.value.toUpperCase();
    this.ngModelChange.emit(this.value);
  }
}

在添加新表单之前,它的效果很好,这就是我的模型的样子:

 formArray = this.formBuilder.group({
    items: this.formBuilder.array([])
  });

 buildItem(): FormGroup {
    return this.formBuilder.group({
      symbol: new FormControl('', this.vatCategoryValidation.bind(this)),
      value: new FormControl('', this.vatValueValidation.bind(this))
    });
  }
 addItem() {
    this.items.push(this.buildItem());
  }

当前存在两个问题,第一个问题是@Output值传播到每个输入而不是与此相关的每个输入。其次是错误xpression has changed after it was checked. Previous value: 'ng-valid: false'. Current value: 'ng-valid: true'.

enter image description here 是否可以使其协同工作?

1 个答案:

答案 0 :(得分:0)

好吧,我通过修改一下我的指令一次解决了两个问题:

@Directive({
  selector: '[appUppercase]'
})
export class UppercaseDirective {
  @Output() ngModelChange: EventEmitter<any> = new EventEmitter();
  value: any;

  constructor(private el: ElementRef) {}

  @HostListener('input') onInputChange() {
    this.el.nativeElement.value = this.el.nativeElement.value.toUpperCase();
  }
}