Use @HostBindings instead of host in angular 4

I am just trying to do animation with angular 4 and I saw a tutorial which uses host in component

import { Component, OnInit, HostBinding } from '@angular/core';
import { AngularFire, AuthProviders, AuthMethods } from 'angularfire2';
import { Router } from '@angular/router';
 import { moveIn } from '../router.animations';

@Component({
selector: 'app-login',
templateUrl: './login.component.html',
styleUrls: ['./login.component.css'],
animations: [moveIn()],
host: {'[@moveIn]': ''}
})

      

but it shows me an error in the host property "[tslint] uses @hostBindings and @HostListeners instead of host property"

+4


source to share


3 answers


tslint

are not errors. These are TypeScript shedding messages generated by the tslint webpack service.

You can read more about TSLint here:

https://palantir.github.io/tslint/

For some reason, someone decided that using a property host

in a component was bad practice. You can use this feature and other component configuration functions nicely.



To disable this check, select the file tslint.json

and add / change the following:

    "use-host-property-decorator": false

      

Setting this parameter false

disables checking.

+12


source


For those who come across this in the future, I would like to shed some light on why this is a linting error and why or why you don't use the property host

.

So there are several ways to set properties and listen for events on the host component. A property host

in the decorator of the component or with @HostBinding

(for properties) and @HostListener

(for events).

When we use the property host

, we can use the syntax, which is exactly the same as in the templates, []

and ()

and direct properties, such as class

. This is great because you don't need to import anything, and when you look at it, you pretty much know what's going to happen. Now, when you get into more complex scenarios like setting aria properties, your logic in those properties gets more complicated. For example:

@Component({
   selector: 'my-component',
   host: {
     '[attr.aria-expanded]': 'expanded'
   }
})
export class MyComponent {
   expanded: boolean = false
}

      

Here we can see the extended property is used to set the attribute aria-expanded

on the host. Using any tool, be it IDE, TypeScript, LanguageExtensions, we won't be able to see how they are related.

This causes a problem when you are refactoring and you are missing the logic that is in these lines. And when it does, it's real pain.

Therefore, to get around this, you must use a decorator @HostBinding

.

@Component({
   selector: 'my-component'
})
export class MyComponent {
   @HostBinding('attr.aria-expanded')
   expanded: boolean = false
}

      

Now you can change the name of the property to whatever you want and everyone will be happy.


This happens until you get to properties that can affect many attributes of the host element, or that do have some kind of logic.

HostBinding

@Component({
   selector: 'my-component'
})
export class MyComponent {
   @HostBinding('attr.aria-expanded')
   @HostBinding('class.expanded')
   expanded: boolean = false
}

      



Some people don't like multiples @HostBindings

for properties. And this can be changed to:

master

@Component({
   selector: 'my-component',
   host: {
      '[attr.aria-expanded]': 'expanded',
      '[class.expanded]': 'expanded',
   }
})
export class MyComponent {
   expanded: boolean = false
}

      

And properties that actually have logic:

HostBinding

@Component({
   selector: 'my-component'
})
export class MyComponent {
   @HostBinding('attr.aria-expanded')
   @HostBinding('class.expanded')
   get expanded(): boolean {
      // Don't actually do this, this is just an example for Hostbinding vs. host
      return this._expanded ? true : null
   }

   // create a setter here as well.

   private _expanded: boolean = false
}

      

against the owner

@Component({
   selector: 'my-component',
   host: {
      '[attr.aria-expanded]': 'expanded ? true : null',
      '[class.expanded]': 'expanded',
   }
})
export class MyComponent {
   expanded: boolean = false
}

      

So now that we know what everyone is doing, we can talk about why properties host

are linted by default.

When using properties, host

there are actually no checks to see if you wrote the property correctly. When you build Angular with AoT (which is commonly used for production), you will most likely get errors and then fix them. It's just faster to get feedback in your editor on use @HostBinding

than waiting for long build progress (depending on how big your application really is).

Thus, due to the fact that almost unknown (today compilers) string values, the use of properties is host

marked by default.

Perhaps in the future, when AoT can be used in development (with the Ivy renderer, I think?) We might get these compiler errors. But we are not there yet.

+1


source


@Reactgular post respose:

To disable this check, edit the tslint.json file and add / change the following:

"use-host-property-decorator": false

      

This property is renamed to: no-host-metadata-property, so the code in tslint.json is:

"no-host-metadata-property": false

      

0


source







All Articles