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"
source to share
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.
source to share
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.
source to share