无法理解 Angular2 组件中 :host 的使用

Posted

技术标签:

【中文标题】无法理解 Angular2 组件中 :host 的使用【英文标题】:Cannot Understand the Use of :host in components in Angular2 【发布时间】:2017-07-23 20:15:16 【问题描述】:

我对 host 的理解是,如果我在父组件中有一个子组件,并且我们想从父组件设置子组件的样式,我们可以使用 :host 。 和 :host-context 反之亦然。 请让我知道这是否正确使用 host 。

https://angular.io/docs/ts/latest/guide/component-styles.html

当我尝试在我的应用程序中做同样的事情时,它不起作用

应用组件模板

  <div class ="top">
    <h1>
      Home Component
    </h1>
    <hr>
    <app-ngrx></app-ngrx>
    <router-outlet></router-outlet>
  <div>

ngrx 组件模板

  <h3 class="mine">NGRX</h3>

<button (click)="increment()">Increment</button>
<div>Current Count:  counter | async </div>
<button (click)="decrement()">Decrement</button>

<button (click)="reset()">Reset Counter</button>

应用组件 CSS

:host(.mine)
  color:red;

这似乎不起作用请帮助我无法理解。

我看了这个问题,但就是想不通

Angular 2: How to style host element of the component?

@Gunter 回答后更新

在我的 app-ngrx 模板中我添加了

  <h3 class = "mine">NGRX</h3>

<button (click)="increment()">Increment</button>
<div>Current Count:  counter | async </div>
<button (click)="decrement()">Decrement</button>

<button (click)="reset()">Reset Counter</button>

在我添加的 app-ngrx css 文件中

:host(.mine)
  color:red;

但即使没有在应用程序组件中添加我的

<app-ngrx></app-ngrx>

h3 是红色的,我觉得 &lt;app-ngrx class = "mine"&gt;&lt;/app-ngrx&gt; 时应该是红色的

【问题讨论】:

我不明白你的更新。 &lt;h3&gt; 不会受到影响。整个&lt;app-ngrx class="mine"&gt; 应该是red。 (&lt;app-ngrx class = "red"&gt;&lt;/app-ngrx&gt; 不应该是红色的,因为 red 是错误的类 - 你可能打算使用 class="mine" @GünterZöchbauer ya class mine,我只希望组件的 h3 为红色,而不是整个模板显示为红色 那就不要使用:host 如果我只想从父级而不是整个模板更新ngrx的h3,因为人们会想要更改按钮颜色或根据父组件类的某些值添加一些类跨度> @GünterZöchbauer 没有主机我们如何从父组件实现这一点我现在很困惑 【参考方案1】: :host ... 选择组件本身

:host(.mine) ... 在设置了class="mine" 时选择组件本身

:host-context(.mine) ... 在其祖先之一设置了class="mine" 时选择组件本身

另见https://angular.io/docs/ts/latest/guide/component-styles.html

@Component(
  selector: 'h3', 
  styles: [':host(.mine)  color: red; ], 
  template: '<ng-content></ng-content>') 
class MyH3Component
<h3 class="mine">this is red</h3>
<h3>this is black</h3>

:host-context

@Component(
  selector: 'h3', 
  styles: [':host-context(.mine)  color: red; ], 
  template: '<ng-content></ng-content>') 
class MyH3Component

<body class="mine">
  <my-app><my-app>
<body>

应用组件

template: '<h3>this is red</h3>'

或设置class="mine"

<body>
  <my-app><my-app>
<body>

应用组件

template: '<h3>this is black</h3>'

更新

如果您想设置子组件的内容(而不是子组件本身)的样式,您可以使用/deep/

:host child /deep/ h3 
  color: red;

更新 2 ::slotted 现在被所有新浏览器支持并且可以与`ViewEncapsulation.ShadowDom 一起使用

https://developer.mozilla.org/en-US/docs/Web/CSS/::slotted

【讨论】:

所以这就像不修改css,而只是根据该选择器选择组件 所以如果我从ngrx模板中删除我的类,它不会被选中,我真的对这个概念感到困惑 如果您有一个带有@Component(selector: 'h3', styles: [':host(.mine) color: red; ], template: '&lt;ng-content&gt;&lt;/ng-content&gt;') class MyH3Component 的组件,那么在&lt;h3&gt; 中添加或删除class="mine" 将在reddefault 之间切换&lt;h3&gt; 的颜色。 然后在不同的组件中添加和删除一个类对吗? 抱歉,不明白您的评论。【参考方案2】:

我对主机的理解是,如果我有一个子组件 在父组件内部,我们想要设置子组件的样式 我们可以使用的父组件 :host 。和 :host-context 为 反之亦然

不,这不是它的用途。

:host 选择器来自shadow DOM spec。

...这个范围子树称为影子树。它的元素 附加到的是它的影子主机。

在 Angular 世界中,组件的模板是阴影树。组件的元素是影子主机。因此,当您为 :host 选择器定义样式时,这些样式将应用于组件的元素。

:主机

在您的示例中,如果您在 my-app 组件中定义了样式,则这些样式将应用于 &lt;my-app&gt; DOM 元素。这个特殊的配置:

:host(.mine)
  color:red;

将应用于具有.mine 类的宿主元素:

<my-app class="active">

如果您在app-ngrx 组件中定义了样式,则样式将应用于&lt;app-ngrx&gt; DOM 元素, &lt;my-app&gt;。这个特殊的配置:

:host(.mine)
  color:red;

将应用于具有.mine 类的宿主元素:

<app-ngrx class="active">

:主机上下文

现在,:host-context 也应用于宿主元素,但函数(括号)采用一个选择器,该选择器不是针对宿主元素本身,而是针对文档根之前的所有祖先。如果找到此类元素,则应用样式。

比如这个选择器

:host(.mine)
  color:red;

匹配这样的结构:

<my-app class="mine">

而这个选择器:

:host-context(.mine)
  color:red;

匹配这个结构:

<div class="mine">
 ...
   <my-app>

如果您想有条件地将样式应用于组件视图(阴影根),这很有用。这使得h2 总是粗体:

h2 
   font-weight: bold;

而这个

:host-context(.make-inner-components-bold) h2 
  font-weight: bold;

仅当您的组件位于类为 .make-inner-components-bold 的元素内时,它们才会变为粗体。

【讨论】:

以上是关于无法理解 Angular2 组件中 :host 的使用的主要内容,如果未能解决你的问题,请参考以下文章

Angular2无法从导入的模块中识别组件

Angular2 - 删除所有/最近的子组件后无法添加子组件

Angular2 RC5:无法绑定到“属性 X”,因为它不是“子组件”的已知属性

Angular2 RC5:无法绑定到“属性 X”,因为它不是“子组件”的已知属性

如何将一个组件放入Angular2中的另一个组件中?

Angular 2 - 无法解析组件的所有参数:(?)