Angular 6反应形式-触发对焦点/模糊的验证

时间:2018-07-27 08:37:20

标签: angular angular-reactive-forms reactive-forms

如何在模糊/聚焦/改变时触发验证消息?

我尝试过的事情:

import { FormGroup, Validators, FormBuilder, FormControlName, FormControl } from '@angular/forms';

// Component - Class implementation:

addressForm: FormGroup;

consructor(private fb: FormBuilder) { }

ngOnInit() {
    this.addressForm = this.fb.group({
      zip: ['', {
        validators: [Validators.required, Validators.minLength(4)],
        updateOn: 'change' //blur
      }] 
    });
}

但这不起作用。

3 个答案:

答案 0 :(得分:1)

您可以在表单中使用模板驱动器验证,而不是使用反应式表单验证。 下面是相同的示例:

<div class="group input-group input-group-sm has-feedback" [ngClass]="{'has-success' : contact_name.valid && contact_name.touched,'has-error' : contact_name.invalid && contact_name.touched}">
    <div class="font-icn input-group-addon">
        <i class="fa fa-calendar"></i>
    </div>
    <input type="number" min="0" class="input_k" name="contact_name" id="contact_name" [value]="contactForm.contact_name"
    [(ngModel)]="contactForm.contact_name" #contact_name="ngModel" >
    <label for="contact_name" [ngClass]="{'active' : contactForm.contact_name != ''  }">Enter Contact Form</label>
    <span aria-hidden="true" class="fa form-control-feedback" [ngClass]="{'fa-check': contact_name.valid && contact_name.touched,'fa-remove' : contact_name.invalid && contact_name.touched}"></span>
    <div class="help-block" *ngIf="contact_name.invalid && contact_name.touched">Please select contact form.</div>
</div>

答案 1 :(得分:1)

我也遇到了这个问题,我像往常一样通过指令和服务解决了这个问题。该指令附加到输入元素,服务协调应触发验证的事件。

指令如下:

@Directive({
    selector: 'input, textarea, select'
})
export class TriggerValidationDirective {
    constructor(private svc: TriggerValidationService, private el: ElementRef) {
    }

    @HostListener('blur', ['$event'])
    @HostListener('selectionChange', ['$event'])
    @HostListener('change', ['$event'])
    onTriggerValidation(e) {
        this.svc.triggerValidation(this.el);
    }
}

这里是服务

@Injectable({ providedIn: 'root' })
export class TriggerValidationService {
    private triggerValidationSubject = new Subject<ElementRef | null>();

    triggerValidation$ = this.triggerValidationSubject.asObservable();

    triggerValidation(el?: ElementRef<any>) {
        this.triggerValidationSubject.next(el);
    }
}

这是我在包含响应式形式的组件中使用它的方式:

@Component({
  // ... selector, etc.
  providers: [ { provide: TriggerValidationService, useClass: TriggerValidationService } ]
})
export class TheComponent implements OnInit, OnDestroy {

  constructor(private triggerValidationService: TriggerValidationService) {}

  ngOnInit() {
    this.sub = this.triggerValidationService.triggerValidation$.subscribe(_ => {
      // trigger validation, e.g. this->formGroup.updateValueAndValidity();
    });
  }

  ngOnDestroy() {
    this.sub.unsubscribe();
  }
}

简要回顾其工作原理:该指令附加到所有相关的输入元素(文本输入、文本区域、日期选择器、选择等)并侦听我们想要用来触发验证的适当事件。该指令然后通知在 observable 上发出的服务。托管表单的组件订阅该 observable 并在它发出时执行有效性检查。

重要提示:请注意,该服务必须由托管表单的组件提供(请注意组件装饰器中的 providers 部分),以便不同的表单不会触发每个其他人的验证。

答案 2 :(得分:0)

我从表单上的输入元素中观察模糊事件。然后我合并 valueChanges 并像这样模糊观察对象:

  ngAfterViewInit(): void {
    // Watch for the blur event from any input element on the form.
    // This is required because the valueChanges does not provide notification on blur
    const controlBlurs: Observable<any>[] = this.formInputElements
      .map((formControl: ElementRef) => fromEvent(formControl.nativeElement, 'blur'));

    // Merge the blur event observable with the valueChanges observable
    // so we only need to subscribe once.
    merge(this.productForm.valueChanges, ...controlBlurs).pipe(
      debounceTime(800)
    ).subscribe(value => {
      this.displayMessage = this.genericValidator.processMessages(this.productForm);
    });
  }

我这里有一个完整的例子:https://github.com/DeborahK/Angular-ReactiveForms/tree/master/APM