Angular2:当jquery插件附加到ng-form对象时如何触发ng-valid?

时间:2017-03-08 03:48:42

标签: forms validation angular jquery-plugins

我使用Angular2 ng-form,我喜欢它如何自动确定表单上的所有控件是否有效,如果是,则启用我的表单提交按钮。 但是,如果我在其中一个控件上使用一个很酷的jquery插件,比如我的示例中的datedropper,那么表单将保持无效,直到底层输入控件有效。

这是我的表单HTML:

    <form name="submitForm" #submitForm="ngForm">
      <div class="group">
        <input class="spring-date spring-input" data-large-mode="true" data-large-default="true" required readonly type="text" name="docdate" [(ngModel)]="docdate" #inputdocdate="ngModel">
      </div>
      <div class="group">
        <input class="spring-input" required type="text" name="company" [(ngModel)]="company" #inputcompany="ngModel">
      </div>
      <div class="group">
        <button id="btnSave" type="submit" class="btn btn-default" [disabled]="!submitForm.form.valid">SAVE</button>
      </div>
    </form>

这是jquery来激活dateropper(我在我的TypeScript组件中执行):

ngOnInit() {
        // Initialize Datedropper jquery select box
        $('.spring-date').dateDropper();
    });

即使我在日期工作程序jquery更改事件中更新了我的TS代码中的二重绑定 docdate 值,表单也没有确定它是有效的,直到我开始输入其他文本框控件。

$('.spring-date').on('change', (e: any) => {
            this.docdate = $(e.target).val();                
        });

如何使用jquery插件(如datedropper或Select2),在用户更改值后,更新jquery中的基础输入控件,同时激活Angular2表单验证? < / p>

我唯一的另一个选择是放弃内置的Angular2验证并编写代码以手动验证所有控件。我觉得我错过了一个简单的解决方法。

1 个答案:

答案 0 :(得分:1)

在您的情况下,在角度区域内调用onChange会对您有所帮助:

$('.spring-date').dateDropper().on('change', (e: any) => {
   // console.log(Zone.current.name); // prints <root>
   this.ngZone.run(() => {
     // console.log(Zone.current.name); // prints angular
     this.docdate = e.target.value;
   });
});
  

如何使用jquery插件(如datedropper或Select2)及之后   用户更改值,更新基础输入控件   jquery并同时激活Angular2表单验证?

我会实现ControlValueAccessor之类的:

export const DATE_DROPPER_VALUE_ACCESSOR: any = {
  provide: NG_VALUE_ACCESSOR,
  useExisting: forwardRef(() => DateDropperValueAccessor),
  multi: true
};

@Directive({
  selector: 'input.spring-date',
  providers: [DATE_DROPPER_VALUE_ACCESSOR]
})
export class DateDropperValueAccessor implements ControlValueAccessor {
  constructor(private _renderer: Renderer, private _elementRef: ElementRef, private ngZone: NgZone) { }

  writeValue(value: any): void {
    this._renderer.setElementProperty(this._elementRef.nativeElement, 'value', value);
  }

  ngOnInit() {
    $(this._elementRef.nativeElement).dateDropper().on('change', (e: any) => {
      this.ngZone.run(() => this.onChange(e.target.value));
    });
  }

  onChange = (_: any) => { };
  onTouched = () => { };

  registerOnChange(fn: (_: any) => void): void { this.onChange = fn; }
  registerOnTouched(fn: () => void): void { this.onTouched = fn; }
}

<强> Plunker Example

另见