DEV Community

Cover image for Using @HostBinding
Rudra Siva
Rudra Siva

Posted on • Edited on

Using @HostBinding

Feel free to skip the detailed steps and jump directly to the stackblitz demo at the end of the post

@HostBinding lets you set properties on the host element or component.

Steps to be followed

  1. As a good practice, create a separate directory to place all your custom directives in your angular project. I have a created a new folder name directives under the src/app directory

    Create Directory

  2. Create a new file border.directive.ts inside the directives directory

    Create File

  3. In the border.directive.ts file, create a usual typescript class just as below.

    export class BorderDirective {
    }
    
    
  4. To make this class as a attribute directive, we need to decorate it with @Directive annotation

    @Directive()
    export class BorderDirective {  
    
    }
    
  5. We must give this directive a name using the selector property just as we do for a @Component. The name we give here will be used in the html files.

    @Directive({
        selector: '[border]'
    })
    export class BorderDirective {
    
    }
    
  6. In the above step, if you notice, we have surronded the name with [] because this directive will be an attribute directive. But in case of @Component we don't surround the selector with brackets because they will be used as tags < > in the html templates.

  7. By this point, you might notice an error for @Directive. To fix that, add the import statement as the first line in the file.

    import { Directive } from '@angular/core';
    
  8. To use this new custom directive we have to declare it in our module app.module.ts.

    import { NgModule } from '@angular/core';
    import { BrowserModule } from '@angular/platform-browser';
    import { FormsModule } from '@angular/forms';
    
    import { AppComponent } from './app.component';
    import { BorderDirective } from './directives/border.directive.ts';
    
    @NgModule({
        imports:      [ BrowserModule, FormsModule ],
        declarations: [ AppComponent, BorderDirective ],
        bootstrap:    [ AppComponent ]
    })
    export class AppModule { }
    
  9. That's it! Our new custom directive is ready to be added to any DOM element or component. Let's add this to a <div> tag in our app.component.html

    <div border>
        This is a simple div with 'border' attribute
    </div>
    
  10. If you run the application, you won't see any border around the div. Because we didn't specify anything in our border.directive.ts when border attribute is found on a DOM element.

  11. To do that, lets add the below snippet to our BorderDirective class in the border.directive.ts file

    @HostBinding('style.borderStyle')
    get style() {
        return 'solid';
    }
    
  12. @HostBinding decorator binds the property specified in the argument to the host DOM element. In the above snippet, we binded the border-style property to the host element.

  13. You might notice an error for @HostBinding, to fix that add the required import.

    import { Directive, HostBinding } from '@angular/core';
    
  14. Now if you run the application, you will find a solid border around the div. Yay!!

    Alt Text

  15. But if you notice, we are not done yet. Because, the style is border is same and not configurable. So we must provide a way to the consumer(i.e., div or any DOM element) to provide the styles they want.

  16. So let's add an input property in the BorderDirective class and update the style() method as below. If the consumer doesn't provide the bStyle attribute, then it will be defaulted to 'solid'.

    @Directive({
    selector: '[border]'
    })
    export class BorderDirective {
        @Input() bStyle: string = 'solid';
    
        @HostBinding('style.borderStyle')
        get style() {
            return this.bStyle;
        }
    }
    
  17. Don't forget to add the import for @Input.

    import { Directive, HostBinding, Input } from '@angular/core';
    
  18. Now add another div to our html file as below and verify the output

    <div border>
        This is just a div with border directive
    </div>
    
    <div border bStyle='dotted'>
        This is just a div with border directive and specifies the style using the bStyle property
    </div>
    

    Alt Text

  19. Similarly we can add and customize various properties for the border.

    import { Directive, HostBinding, Input } from '@angular/core';
    
    @Directive({
    selector: '[border]'
    })
    export class BorderDirective {
        @Input() bStyle: string = 'solid';
        @Input() bRadius: number = 10;
        @Input() bPadding: number = 10;
        @Input() bMargin: number = 10;
        @Input() bColor: string = 'lightgrey';
        @Input() bWidth: number = 2;
    
        @HostBinding('style.borderStyle')
        get style() {
            return this.bStyle;
        }
    
        @HostBinding('style.borderRadius')
        get radius() {
            return `${this.bRadius}px`;
        }
    
        @HostBinding('style.padding')
        get padding() {
            return `${this.bPadding}px`;
        }
    
        @HostBinding('style.margin')
        get margin() {
            return `${this.bMargin}px`;
        }
    
        @HostBinding('style.borderColor')
        get color() {
            return this.bColor;
        }
    
        @HostBinding('style.borderWidth')
        get thickness() {
            return `${this.bWidth}px`;
        }
    }
    

Stackblitz Demo

Top comments (0)