Angular ControlValueAccessor with default value from internal causes dirty

Discussão em 'Angular' iniciado por Daniel, Outubro 15, 2024.

  1. Daniel

    Daniel Guest

    I have a directive to build dynamic Input components for a template driven form. The default value is set by the Input component itself.

    The problem is that setting a default value causes that the form is marked as dirty.

    How is it possible to archieve setting a default value from inside of the Directive without marking the form as dirty?

    @Directive({
    selector: '[myFormInputFactory]',
    providers: [
    { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => MyFormFactoryDirective), multi: true }
    ]
    })
    export class MyFormFactoryDirective implements OnChanges, OnDestroy, ControlValueAccessor {
    @Input() myFormInputFactory: DialogItem;

    private componentRef: any;
    private value: any;
    private valueSubscription: Subscription;
    private disabled = false;

    constructor(
    private viewContainerRef: ViewContainerRef,
    private componentFactoryResolver: ComponentFactoryResolver,
    private _renderer: Renderer,
    private _elementRef: ElementRef
    ) { }

    onChange = (_: any) => { };
    onTouched = () => { };

    registerOnChange(fn: (_: any) => void): void { this.onChange = fn; }
    registerOnTouched(fn: () => void): void { this.onTouched = fn; }


    ngOnChanges(changes: SimpleChanges) {
    if ('myFormInputFactory' in changes) {
    const config = changes['myFormInputFactory'].currentValue as IConfigItem;

    const factories = Array.from(this.componentFactoryResolver['_factories'].values());
    const comp = factories.find((x: any) => x.selector === config.selector) as ComponentFactory<{}>;
    const componentRef = this.viewContainerRef.createComponent(comp);

    if (this.componentRef) {
    this.componentRef.destroy();
    }
    this.componentRef = componentRef;
    this.valueSubscription = this.componentRef._component.valueChange.subscribe(value => {
    this.value = value;
    this.onChange(this.value);
    });
    }
    }

    ngOnDestroy() {
    if (this.valueSubscription) {
    this.valueSubscription.unsubscribe();
    }
    }

    writeValue(value: string): void {
    if (this.value !== null) {
    this.onChange(this.value);
    }
    if (value !== undefined && value !== null) {
    this.value = value;
    }
    }
    }



    UPDATE

    I have created a StackBlitz

    Continue reading...

Compartilhe esta Página