使用@HostBindings 代替 angular 4 中的主机

Use @HostBindings instead host in angular 4

我只是尝试用 angular 4 制作动画,我看到了在组件中使用主机的教程

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]': ''}
})

但在主机下显示错误 属性 “[tslint] 使用@hostBindings 和@HostListeners 而不是主机属性”

tslint 不是错误。它们是由 tslint webpack 服务创建的 TypeScript linting 消息。

您可以在此处阅读有关 TSLint 的更多信息:

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

出于某种原因,有人认为在组件中使用 host 属性 是一种不好的做法。您完全可以使用该功能以及其他组件配置功能。

要禁用此 lint 检查,请编辑您的 tslint.json 文件和 add/modify 以下内容:

    "use-host-property-decorator": false

将其设置为 false 将禁用检查。

对于那些将来遇到此问题的人,我想阐明为什么它是一个 linting 错误,以及为什么或为什么不应该使用 host 属性。

因此,有几种方法可以在主机组件上设置属性和侦听事件。组件装饰器中的 host 属性 或 @HostBinding(对于属性)和 @HostListener(对于事件)。

当我们使用 host 属性 时,我们可以使用与模板、[]() 完全相同的语法以及 [=23 这样的直接属性=].这很棒,因为您不必导入任何东西,当您查看它时,您几乎就会知道会发生什么。现在,当你进入一些更复杂的场景时,比如设置 aria 属性,你在这些属性中的逻辑会变得复杂。例如:

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

这里我们可以看到扩展的属性是用来设置host上的aria-expanded属性的。使用任何工具,无论是 IDE、TypeScript、LanguageExtensions,我们都无法看到两者之间存在关联。

这会在您进行重构时导致问题,并且您错过了那些字符串中的逻辑。当这种情况发生时,那将是一种真正的痛苦。

所以要解决这个问题,您可以使用 @HostBinding 装饰器。

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

现在您可以将 属性 的名称更改为任何您想要的名称,大家都很高兴。


直到您获得可能影响多个宿主元素属性的属性,或者实际上具有某种逻辑的属性。

主机绑定

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

有些人不喜欢 属性 上的多个 @HostBindings。并且可以更改为:

主机

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

以及实际具有逻辑的属性:

主机绑定

@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
}

对比 主机

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

所以,既然我们知道了每个属性的作用,我们就可以讨论为什么 host 属性在默认情况下会被 linter 标记。

使用 host 属性时,实际上并没有检查您是否正确拼写了 属性。当您使用 AoT(通常用于生产)构建 Angular 时,您很可能会遇到错误,然后进行修复。使用 @HostBinding 时可以更快地在编辑器中获得反馈,而不是等待漫长的构建过程(实际上取决于您的应用程序有多大)。

因此,由于(对于今天的编译器而言)几乎未知的字符串值,默认情况下会标记使用 host 属性。

也许将来当 AoT 可以用于开发时(我想是用 Ivy 渲染器?),我们可能会得到那些编译器错误。但与此同时,我们还没有。

@Reactgular post 响应:

要禁用此 lint 检查,请编辑您的 tslint.json 文件和 add/modify 以下内容:

"use-host-property-decorator": false

这个属性重命名为:no-host-metadata-property 所以tslint.json中的代码是:

"no-host-metadata-property": false