我遇到以下情况,这是行不通的:
1)一种反应形式:
<form [formGroup]="formGroup">
<ng-template [doDynamicForm]="field1" [formCtrlName]="indexfield"></ng-template>
</form>
2)doDynamicForm指令,该指令决定要在ng-template中呈现的Component:
@Directive({ selector: '[doDynamicForm]'})
export class DynamicFormDirective implements OnInit {
private _field: Field;
private _formCtrlName: string;
constructor(private viewContainerRef: ViewContainerRef,
private resolver: ComponentFactoryResolver) {
}
@Input()
set doDynamicForm(field: Field) {
this._field = field;
}
/**
* Nome per il from controller
* @param value
*/
@Input()
set formCtrlName(value: string){
this._formCtrlName = value;
}
ngOnInit() {
this.generateView();
}
private generateView(): void {
const atype = this.field.datatype;
switch (atype) {
case "String":
const factory = this.resolver.resolveComponentFactory(InputComponent);
const ref = this.viewContainerRef.createComponent(factory, 0);
let instance =ref.instance;
instance.pHolder = this._attribute.name;
instance.ctrlName = this._ctrlName;
break;
case "Date":
//TODO
break;
case "Choice":
//TODO
break;
default:
throw "Unsupported Attribute type " + atype;
}
}
}
我得到的是正确呈现InputComponent中设计的输入文本字段,但是输入字段上的事件没有传播到外部表单。
如果我省略指令并直接使用InputComponent,那么一切都很好。
InputComponent是这样的:
const CUSTOM_INPUT_CONTROL_VALUE_ACCESSOR: any = {
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => InputComponent),
multi: true
};
@Component({
selector: 'wrap-input',
templateUrl: './input.component.html',
styleUrls: ['./input.component.scss'],
providers: [CUSTOM_INPUT_CONTROL_VALUE_ACCESSOR],
})
export class InputComponent implements OnInit, OnDestroy, ControlValueAccessor {
@Input() pHolder: string;
@Input() ctrlName: string;
@Input() intype = 'text';
control: FormControl = new FormControl('');
private subscription?: Subscription;
private onChange: (_: any) => void = (_: any) => {};
ngOnInit(): void {
this.subscription = this.control.valueChanges.subscribe(v => {
this.onChange(v);
});
}
ngOnDestroy(): void {
if (this.subscription) {
this.subscription.unsubscribe();
}
}
writeValue(val: any): void {
this.control.setValue(val, { emitEvent: false });
}
registerOnChange(fn: (_: any) => void): void {
this.onChange = fn;
}
registerOnTouched(fn: any): void {}
有什么主意吗?
谢谢!