Categories
Angular Opinions Tutorials

Understanding Angular Checkbox Directives and Host Binding

Imagine we have directive that customizes the checkbox color and interaction.

import { Directive } from '@angular/core';

@Directive({
  selector: '[tnb-checkbox]',
})
export class TnbCheckbox {  
}

We want to make our checkbox checked base on certain condition.

import { Directive } from '@angular/core';

@Directive({
  selector: '[tnb-checkbox]',
  '[checked]: 'isAllChecked()'
})
export class TnbCheckbox { 
  isAllChecked() {

  } 
}

But line 5, the highlighted one will throw following error.

An error by Angular Compiler 

Can't bind to 'checked' since it isn't a known property of 'ng-directive'.
Error message indicating an issue with binding the ‘checked’ property in Angular directive.

What really happens is that Angular thinks we are binding directive on some host elements (container etc) that doesn’t have checked property.

Angular couldn’t determine the host is input checkbox, it treats the host as generic element.

But we can solve it by applying constraints to the selector, If our selector targets an actual <input type="checkbox>

import { Directive } from '@angular/core';

@Directive({
  selector: '[tnb-checkbox]input[type="checkbox"]',
  '[checked]: 'isAllChecked()'
})
export class TnbCheckbox { 
  isAllChecked() {

  } 
}

With the selector, Angular knows the host element is <input> (specifically a checkbox). The DOM type HTMLInputElement does have checked attribute (along with others properties like intermediate)

Angular template checking is type aware. Since Angular Version 20, the host binding is improved. We have type checking for host binding and listener expressions.

It will be really interesting to find out how the compound selector string is translated to host binding type checking.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.