【问题标题】:Angular 2 Directive implementing ControlValueAccessor doesn't update 'touched' property on change实现 ControlValueAccessor 的 Angular 2 指令不会在更改时更新 'touched' 属性
【发布时间】:2017-04-03 08:01:05
【问题描述】:

我正在尝试为 Jquery UI Datepicker 创建自己的 Angular 2 指令。我在互联网上和 SO 中也看到了一些不同的方法,但没有人达到我想要的目标。所以这是我到目前为止的代码:

import {Directive, ElementRef, Input, forwardRef} from '@angular/core';
import {ControlValueAccessor, NG_VALUE_ACCESSOR} from "@angular/forms";

declare  var $:any;

@Directive({
  selector: '[date-picker]',
  providers: [{
    provide: NG_VALUE_ACCESSOR,useExisting:
      forwardRef(() => DatePickerDirective),
    multi: true
  }]
})
export class DatePickerDirective implements ControlValueAccessor {
  private value: string;

  @Input('changeMonth') changeMonth:boolean = true;
  @Input('changeYear') changeYear:boolean = true;

  constructor(private el: ElementRef) {

  }

  ngAfterViewInit(){
    $(this.el.nativeElement).datepicker({
      changeMonth: this.changeMonth,
      yearRange: "1:100",
      changeYear: this.changeYear
    }).on('change', e => this.onChange(e.target.value));
  }

  onChange: Function = () => {};

  onTouched: Function = () => {};

  writeValue(val: string) : void {
    this.value = val;
  }

  registerOnChange(fn: Function): void {
    this.onChange = fn;
  }

  registerOnTouched(fn: Function): void {
    this.onTouched = fn;
  }
}

发生的情况是,即使我选择了一个日期(选择器)或直接在输入字段中键入它,它也不会更新“触摸”属性。

你有什么解决办法吗?

【问题讨论】:

  • 它已经在ng2-bootstrap和ng-bootstrap两个地方实现了,你介意看一下angular2版本的bootstrap,你可以查看here?
  • @PankajParkar 是的!实际上我以前见过它,由于不同的原因,它并不是我所需要的。我需要定制不同的东西。第一步(也是挑战)是我之前提到的。

标签: angular angular2-template angular2-directives


【解决方案1】:

对于那些最终遇到同样问题的人,我想出了一种解决方法,如下所示:

import {Directive, ElementRef, Input, forwardRef} from '@angular/core';
import {ControlValueAccessor, NG_VALUE_ACCESSOR} from "@angular/forms";

declare  var $:any;

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

@Directive({
  selector: '[date-picker]',
  host: {'(blur)': 'onTouched($event)'},
  providers: [CUSTOM_INPUT_DATE_PICKER_CONTROL_VALUE_ACCESSOR]
})
export class DatePickerDirective implements ControlValueAccessor {
  private innerValue: string;

  @Input('changeMonth') changeMonth:boolean = true;
  @Input('changeYear') changeYear:boolean = true;

  constructor(private el: ElementRef) {
    $(this.el.nativeElement).datepicker({
      changeMonth: true,
      changeYear: true,
      dateFormat: 'dd/mm/yy'
    }).on('change', e => this.onChange(e.target.value));
  }

  public onChange: any = (_) => { /*Empty*/ }
  public onTouched: any = () => { /*Empty*/ }

  get value(): any {
    return this.innerValue;
  };

  //set accessor including call the onchange callback
  set value(v: any) {
    if (v !== this.innerValue) {
      this.innerValue = v;
      this.onChange(v);
    }
  }

  writeValue(val: string) : void {
    this.innerValue = val;
  }

  registerOnChange(fn: any): void {
    this.onChange = fn;
  }

  registerOnTouched(fn: any): void {
    this.onTouched = fn;
  }
}

【讨论】:

  • 感谢您回答自己的问题。帮助了我!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-07-27
  • 1970-01-01
  • 2020-03-03
  • 1970-01-01
  • 2017-09-16
  • 1970-01-01
相关资源
最近更新 更多