DEV Community

Discussion on: Wrapping Angular Material button in custom Angular component (part 2)

 
benlune profile image
Benoît Plâtre

Hi Dzhavat,
The way the component was created, with static providers, made the properties on the wrapper impossible to be bound on the final button component. Once the disabled property was set, it couldn't be updated.
I found a way to be able to update value from Wrapper to button instance.
I created a private validateDisabled function which update the button instance isDisables @Input (which is no more injected).

#validateDisabled(firstChange: boolean) {
    if (this.componentRef?.instance) {
      this.componentRef.instance.isDisabled = this.disabled;
      const changes = {
        isDisabled: new SimpleChange('', this.disabled, firstChange),
      };
      this.componentRef.instance.ngOnChanges(changes);
    }
  }
Enter fullscreen mode Exit fullscreen mode

Calling ngOnChange on the dynamically created component seems to be the only way to force the update of the component's properties.
The ButtonTemplate now has more properties

export interface ButtonTemplate {
  target: ElementRef<HTMLButtonElement>;
  isDisabled: boolean;
  ngOnChanges(changes: SimpleChanges): void;
}
Enter fullscreen mode Exit fullscreen mode

For example, here is the AccentButtonComponent

export class AccentButtonComponent implements ButtonTemplate, OnChanges {
  @Input()
  isDisabled = false;

  @ViewChild('target', { static: true, read: ElementRef })
  target!: ElementRef<HTMLButtonElement>;

  constructor(
    @Inject(typeAttributeToken) public type: BheButtonType,
    private cdr: ChangeDetectorRef
  ) {}

  ngOnChanges(changes: SimpleChanges): void {
    this.cdr.detectChanges();
  }
}
Enter fullscreen mode Exit fullscreen mode
Thread Thread
 
dzhavat profile image
Dzhavat Ushev Playful Programming Angular

Hey Benoît,
Thanks for sharing your solution. Appreciate it!
I haven't looked at it in details yet but will do that in the coming days and share my thoughts :)