Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

@HostBinding('disabled') not working with Angular material 12

A custom directive ...

@Directive({
  selector: '[myDirective]',
})
export class MyDirective {

  @HostBinding('disabled')
  disabled = true;

  constructor() { }

  @Input('myDirective')
  set myData(data: string[]) {
    this.disabled = someDirectiveLogic(data);
  }
  
  // ...
}

... has some specific logic to disable a button. When using the directive on a plain HTML button:

<a mat-raised-button color="accent"
  [disabled]="system.selection.length === 0"
>View</a>

<button color="accent"
  [myDirective]="system.selection"
>Pause</button>

The directive works well:

  • No selection, disables the button on the right: Standard button, no selection and disabled state
  • Selecting data, enables the button the right: Standard button, selection and enabled state

When adding the mat-raised-button property on the Pause button with Angular Material v12, the button always shows as enabled: Material button, no selection and should be disabled

The same code works well with Angular Material v6.3, the disabled attribute set by directive will render well in combination with mat-raised-button.

Cannot we use @HostBinding('disabled') with Angular material 12 ?

like image 780
adelinor Avatar asked Nov 07 '25 01:11

adelinor


2 Answers

After looking at the source code for the Angular Material button, I found a solution which works with a standard button, and a material button.

As in line 70 of button.ts, I noticed that using the host property metadata instead of the HostBinding decorator, works as expected. So the directive is now implemented as:

@Directive({
  selector: '[myDirective]',
  host: {
    '[attr.disabled]': 'disabled || null',
    '[class.mat-button-disabled]': 'disabled',
  },
})
export class MyDirective {

  disabled = true;

  constructor() { }

  @Input('myDirective')
  set myData(data: string[]) {
    this.disabled = someDirectiveLogic(data);
  }
  
  // ...
}

This example is illustrated in stackblitz.com .

like image 165
adelinor Avatar answered Nov 09 '25 19:11

adelinor


Just to clarify the answer by adelinor,

The disabled property of a <button> is a Boolean attribute, whose presence represents true, and absence false.

Testing out how Boolean values bound by Angular are reflected in HTML, notice that [attr.disabled]="true" and [attr.disabled]="false" result in <button disabled="true"> and <button disabled="false"> respectively. The disabled attribute is present on both and therefore they are disabled.

Angular's attribute binding syntax removes the attribute altogether if the bound value is null or undefined, which is why the expression disabled || null works.

like image 23
ravindUwU Avatar answered Nov 09 '25 19:11

ravindUwU



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!