私は完全にあなたの要件が何であるかを理解していないが、私はあなたに多分あなたを助けるいくつかのアイデアを与えることができます。
のでControlValueAccessor
とValidator
を実装して、当社のカスタムフィールド(同期)から始めましょう:私たちが使用上のディレクティブで
@Directive({
selector: 'my-field[formControlName],my-field[ngModel]',
providers: [{
provide: NG_ASYNC_VALIDATORS,
useExisting: forwardRef(() => CustomAsyncValidator),
multi: true
}]
})
class CustomAsyncValidator implements AsyncValidator {
valueAccessor: MyFieldComponent;
constructor(@Optional() @Self() @Inject(NG_VALUE_ACCESSOR) valueAccessors: ControlValueAccessor[]) {
this.valueAccessor = valueAccessors.find(x => x.constructor === MyFieldComponent) as MyFieldComponent;
}
// the same as above. I would use it
// constructor(@Self() private valueAccessor: MyFieldComponent) {}
/**
* presents global validation result async + sync
*/
validate(control: AbstractControl): Observable<any> {
return Observable.fromPromise(fakeAsyncValidator(1000)(control)).map(asyncResult => {
return Object.assign({}, asyncResult, this.valueAccessor.validationResult);
});
}
}
function fakeAsyncValidator(timeout: number = 0) {
return (c: AbstractControl) => {
let resolve: (result: any) => void;
const promise = new Promise(res => { resolve = res; });
const res = { 'async': false };
setTimeout(() => resolve(res), timeout);
return promise;
};
}
:AsyncValidator
を実装することを宣言ディレクティブの後
@Component({
selector: 'my-field',
template: `<p>Some markup</p>`,
providers: [
{ provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => MyFieldComponent), multi: true },
{ provide: NG_VALIDATORS, useExisting: forwardRef(() => MyFieldComponent), multi: true }
]
})
export class MyFieldComponent implements ControlValueAccessor, Validator {
onChange = (_: any) => { };
onTouched =() => { };
constructor(private _renderer: Renderer, private _elementRef: ElementRef) { }
writeValue(value: any): void {
const normalizedValue = value == null ? '' : value;
this._renderer.setElementProperty(this._elementRef.nativeElement, 'value', normalizedValue);
}
registerOnChange(fn: (_: any) => void): void { this.onChange = fn; }
registerOnTouched(fn:() => void): void { this.onTouched = fn; }
validationResult: any;
validate(c: FormControl) {
this.validationResult = { 'sync': true };
return null;
}
}
私たちのカスタムフィールド(my-field
)と同じセレクターは、NG_ASYNC_VALIDATORS
を提供し、既存のコンポーネントをコンストラクターに注入します(2つのオプションがあります)。
そして最後に、我々はあなたが望むものと同様のものをやろうとしているこのディレクティブでvalidate
方法があります。
Plunker Example
'FieldEntityReferenceComponent'は何ですか? – yurzui
申し訳ありませんが、コピー貼り付けが間違っていた...それは 'MyFieldComponent'と言うべきです – AngularChef