Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

I am trying to add a validator to my dynamic component loader, however, it doesn't seem to be working. What is it that I am missing? Stackblitz

Here is how my form is setup. I have an button that checks the forms invalid property, it should then toggle on/off based on if the component loader is valid.

<form #f="ngForm" class="role-add-modify" autocomplete="off">
  <div *ngFor="let field of fields;index as idx">
    <ui-component-loader #componentLoader
                         [(ngModel)]="field.value" [name]="field.id"
                         [required]="field.required" [field]="field"
                         [disabled]="field.disabled"
                         *ngIf="field.component">
    </ui-component-loader>
  </div>
  <button *ngIf="state === ModalEditState.Edit" (click)="editItem()"
          [disabled]="f.invalid || !f.dirty">Save Edits
  </button>
</form>

Next I have the component loader which implements ControlValueAccessor. in the parent class AccessorComponent (already works on components with a input in the template).

@Component({
  selector: 'ui-component-loader',
  template: '<ng-template componentHost></ng-template>'
})
export class ComponentLoaderComponent<T extends IComponentLoader> extends AccessorComponent implements OnInit {
  public get invalid() {
    console.log('invalidator');
    return (!this.componentRef?.instance.validate()) || true;
  }

  public get valid() {
    console.log('validator');
    return this.componentRef?.instance.validate() || false;
  }

  public ngOnInit() {
    this.loadComponent();
  }

  public loadComponent() {
    // Dynamically loads the component and saves it to `componentRef`
    const componentFactory = this.componentFactoryResolver.resolveComponentFactory(this.field.component);

    const viewContainerRef = this.componentHost.viewContainerRef;
    viewContainerRef.clear();

    this.componentRef = viewContainerRef.createComponent(componentFactory);
  }
}

Finally, I added the providers to my @NgModule as noted here (I am not sure if both providers are needed or not).

@NgModule({
  providers: [
    { provide: NG_VALIDATORS, useExisting: ComponentLoaderComponent, multi: true },
    { provide: NG_VALUE_ACCESSOR, useExisting: ComponentLoaderComponent, multi: true }
  ]
})
export class UIModule { }

The html inside of the component that gets loaded by the ComponentLoaderComponent looks like this:

<div *ngFor="let item of displayData;index as idx" [id]="'client-role_'+idx">
  <select-field>
    <select-options
          (onDropdownChange)="onClientChange(item, $event, roleSelect)"
          defaultLabel="Select One..."
          [(ngModel)]="item.selectedClient" [required]="true"
          [name]="'clients'+idx"
          [itemList]="item.clients">
    </select-options>
  </select-field>
</div>

When I make a change in the component (pictured below), I would expect invalid or valid to execute, however, neither of the two getters are getting called.

The output looks like this:

Component

question from:https://stackoverflow.com/questions/66051711/ng-value-accessor-not-executing-validations-on-dynamic-component-loader

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
133 views
Welcome To Ask or Share your Answers For Others

1 Answer

Waitting for answers

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...