![](/img/trans.png)
[英]Is it possible to add a custom element as a 'form element' in angularJs so to take advantage of ng-dirty and ng-pristine?
[英]How to update ng-pristine in Custom ControlValueAccessor
我编写了一个简单的CustomValueAccessor来实现pikaday datepicker。 它可以工作,但是当我使用日期选择器选择日期并更新属性时,内部输入控件(通过ngModel绑定到属性)不会更新其ng-pristine类,而外部组件却可以。 我需要将内部输入标记为ng-touched,但我不知道如何实现。
这是我的课:
import { Component, OnInit, Input, Output, EventEmitter, ViewEncapsulation, forwardRef } from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
import { DateService } from "./shared";
import * as pikaday from 'pikaday'
@Component({
selector: 'datepicker',
templateUrl: 'datepicker.component.html',
styles: [require('pikaday/css/pikaday.css')],
encapsulation: ViewEncapsulation.None,
providers: [
// providers to implement formControlName
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => DatePickerComponent),
multi: true
}
]
})
export class DatePickerComponent implements OnInit, ControlValueAccessor {
/**
* ID of the input element
*/
@Input() id: string;
/**
* The minimum date the user can select. Defaults to today. Set to null to not require.
*/
@Input() minDate: Date = new Date();
/**
* Outputs the chosen date string
*/
@Output('date') dateChanged: EventEmitter<string> = new EventEmitter<string>();
/**
* The formatted date value
*/
private _date: string;
constructor() { }
/**
* Initialises the pikaday datepicker
*/
ngOnInit() {
if(!this.id)
throw "Id is required for datepicker"
let options = {
field: document.getElementById(this.id),
format: DateService.datePickerFormat,
onSelect: date => {
this.date = startDatePicker.toString();
}
};
if(this.minDate)
options['minDate'] = this.minDate;
let startDatePicker = new pikaday(options);
}
/**
* Emits the new date
*/
set date(value){
this._date = value;
this.onChangeCallback(value);
this.onTouchedCallback(value);
}
/**
* Returns the date value
*/
get date(){
return this._date;
}
/**
* Push date to parent components (required by ControlValueAccessor)
*/
onChangeCallback = (_: any) => {};
/**
* let formControlValue interface register a touch callback
*/
onTouchedCallback = (_: any) => {};
/**
* Allows parent component to set the onchange handler
*/
registerOnChange(fn) {
this.onChangeCallback = fn;
}
/**
* Allows parent component to set an ontouch handler (not implemented)
*/
registerOnTouched(fn) {
this.onTouchedCallback = fn;
}
/**
* Called when the component is inited with formControlName
*/
writeValue(value: any) {
this.date = value;
}
}
和模板:
<input type="text" [id]="id" [(ngModel)]="date">
这是在使用datepicker设置值之前的HTML:
<datepicker formcontrolname="endDatePicker" id="endDatePicker" ng-reflect-id="endDatePicker" ng-reflect-name="endDatePicker" class="ng-untouched ng-pristine ng-invalid"><input type="text" ng-reflect-model="" ng-reflect-id="endDatePicker" id="endDatePicker" class="ng-untouched ng-pristine ng-valid">
<input type="text" ng-reflect-model="" ng-reflect-id="endDatePicker" id="endDatePicker" class="ng-untouched ng-pristine ng-valid">
</datepicker>
然后是这里:
<datepicker formcontrolname="endDatePicker" id="endDatePicker" ng-reflect-id="endDatePicker" ng-reflect-name="endDatePicker" class="ng-touched ng-dirty ng-valid"><input type="text" ng-reflect-model="19 October, 2016" ng-reflect-id="endDatePicker" id="endDatePicker" class="ng-pristine ng-valid ng-touched">
<input type="text" ng-reflect-model="19 October, 2016" ng-reflect-id="endDatePicker" id="endDatePicker" class="ng-pristine ng-valid ng-touched">
</datepicker>
注意输入控件上的类:ng-pristine和ng-touched。 就我而言,它应该是ng-dirty,而不是ng-pristine。
您可以使用ngControl.control
属性,从实现ControlValueAccessor
本身的组件中将控件标记为原始(或脏的,触摸的,未触摸的):
export class DatePickerComponent implements ControlValueAccessor {
// ...
yourFunction(): void {
let control = this.ngControl.control;
// use any of these to manipulate the state of the control in the form
control.markAsTouched();
control.markAsUntouched();
control.markAsDirty();
control.markAsPristine();
}
}
ngControl.controle是Angular形式在内部使用的AbstractControl对象。 一些文档链接: https : //angular.io/api/forms/AbstractControl
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.