Angular 2如何使CustomValueAccessor有效?

时间:2016-10-12 00:10:42

标签: angular

我有一个实现 CustomValueAccessor 的DateOfBirth组件。

实例化如下:

<div class="form-group" [fieldValidity]="dateOfBirth">
  <label for="name" class="sr-only">Date of birth</label>
  <date-of-birth
    required
    ngDefaultControl
    [(ngModel)]="model.dateOfBirth"
    #dateOfBirth="ngModel"
    name="dateOfBirth">
  </date-of-birth>
  <field-validation-messages field="dateOfBirth"></field-validation-messages>

字段验证消息使用字段参数来访问.errors.required但是它的参数只能解析为字符串“dateOfBirth”而不是控制对象。

如何使此控件可以验证?

供参考,这是组件代码:

const noop = () => {
};
export const CUSTOM_INPUT_CONTROL_VALUE_ACCESSOR: any = {
  provide: NG_VALUE_ACCESSOR,
  useExisting: forwardRef(() => DateOfBirth),
  multi: true
};
@Component({
  moduleId: __moduleName,
  selector: 'date-of-birth',
  templateUrl: 'date_of_birth.html',
  styleUrls: ['date_of_birth.css'],
  encapsulation: ViewEncapsulation.None,
  providers: [CUSTOM_INPUT_CONTROL_VALUE_ACCESSOR]
})
export class DateOfBirth implements ControlValueAccessor {

  @Input() name: string;

  private _viewModel: DateOfBirthVm = new DateOfBirthVm();

  private _yearOptions: Array<number> = [];
  private _monthInputValue: string = '';
  private _monthControl: FormControl = new FormControl();
  private _yearInputValue: string = '';
  private _yearControl: FormControl = new FormControl();

  constructor(private _appSettings: AppSettings) {
    this._monthControl.valueChanges.subscribe((value: string) => {
      this._viewModel.month = value;
      this._onChanged(this._viewModel);
    });
    this._yearControl.valueChanges.subscribe((value: string) => {
      this._viewModel.year = value;
      this._onChanged(this._viewModel);
    });
  }

  ngOnInit() {
    for(let i=(this._appSettings.currentYear-18); i>1909; i--) {
      this._yearOptions.push(i);
    }
  }

  //Interface specific stuff.
  //To notify external component's that the model has changed, we must call our
  //registeredOnChange handler. (e.g _onChanged()). Simply calling it, informs other components.
  registerOnChange(fn: any) { this._onChanged = fn; }
  registerOnTouched(fn: any) { this._onTouched = fn; }
  private _onChanged = (value) => { };
  private _onTouched = () => { };
  //write value is called when an external component writes to our model.
  //e.g if another component with ([ngModel])="myAutoCompleteValue", calls myAutoCompleteValue = '';
  writeValue(vm: DateOfBirthVm) {
    if(!vm) {
      this._viewModel.month = '';
      this._viewModel.year = '';
    } else {
      this._viewModel = vm;
      this._monthInputValue = vm.month;
      this._yearInputValue = vm.year;
      this._onChanged(vm);
    }
  }
}

1 个答案:

答案 0 :(得分:1)

  

字段验证消息使用字段参数来访问.errors.required但是它的参数只能解析为字符串&#34; dateOfBirth&#34;而不是控制对象。

void f(int& x)
{
  x = x + 2;
}
int main() 
{
  int q = 55;
  assign_stuff(std::bind(&f, std::ref(q)));
  std::cout << q << "\n";
  return 0;
}

您需要<field-validation-messages field="dateOfBirth"></field-validation-messages> 周围的括号([]),否则将无法对其进行评估。只使用字符串field

此处来自Angular docs on template syntax

  

记住括号

     

括号告诉Angular评估模板表达式。如果我们忘记括号,Angular会将字符串视为常量并使用该字符串初始化目标属性。它没有评估字符串!

     

不要犯以下错误:

dateOfBirth