16

我只是尝试用 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 而不是主机属性”

4

3 回答 3

28

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

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

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

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

在这里我们可以看到扩展属性是用来设置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 渲染器?),我们可能会得到那些编译器错误。但与此同时,我们还没有到达那里。

于 2019-04-22T13:42:53.533 回答
20

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

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

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

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

要禁用此 lint 检查,请编辑您的tslint.json文件并添加/修改以下内容:

    "use-host-property-decorator": false

将其设置为false禁用检查。

于 2017-07-18T18:08:19.763 回答
7

@Reactgular后响应

要禁用此 lint 检查,请编辑您的 tslint.json 文件并添加/修改以下内容:

"use-host-property-decorator": false

此属性重命名为:no-host-metadata-property,因此 tslint.json 中的代码为:

"no-host-metadata-property": false
于 2019-07-04T15:53:03.867 回答