简体   繁体   English

将类传递给子组件主机

[英]Pass class to children component host

I'm used to React approach where I could basically inject anything anywhere. 我已经习惯了React方法,我基本上可以在任何地方注入任何东西。

I have a dumb Button or app-button component in Angular. 我在Angular中有一个哑巴Buttonapp-button组件。 It's inline-block ( :host class), so its width depends on the content. 它是内联块( :host类),因此其宽度取决于内容。 In this case, I can't override its params like display: block or set width. 在这种情况下,我不能覆盖它的参数,如display: block或set width。 I can do it manually by adding new @Input per param ( [display] , [width] ) but it's not really nice. 我可以通过添加新的@Input每个参数( [display][width] )来手动完成它,但它并不是很好。

The behavior I want to have is an input/directive on this component to provide an explicitly inject class to the inside of the child component. 我想要的行为是此组件上的输入/指令,以向子组件内部提供显式注入类。

In React I would just add prop with the class name and assign it or pass some inline styles, depending on what style system I'm using. 在React中,我只需添加类名称的prop,并指定它或传递一些内联样式,具体取决于我正在使用的样式系统。

Is there any way/lib/util to handle this problem? 是否有任何方式/ lib / util来处理这个问题?

Because of the Angular's ViewEncapsulation you cannot do it the way React does. 由于Angular的ViewEncapsulation你不能像React那样做。

Your best bet is to style the button :host element directly. 你最好的选择是直接设置按钮:host元素。 This way you can override it with classes defined in the parent component. 这样,您可以使用父组件中定义的类覆盖它。

app-button.component.ts APP-button.component.ts

import { Component, Input } from '@angular/core';

@Component({
  selector: 'app-button',
  template: `
    I am red by default
  `,
  styles: [`
  :host {
    background-color: red;
  }
  `]
})
export class ButtonComponent {}

app.component.ts app.component.ts

import { Component } from '@angular/core';

@Component({
  selector: 'my-app',
  template: `
  <app-button class="button"></app-button>
  `,
  styles: [
    `.button { 
       background-color: blue; 
     }
    `
  ]
})
export class AppComponent  {}

Live demo 现场演示

You should not write CSS rules for a child component elements in a parent component, since an Angular component is a self-contained entity which should explicitly declare what is available for the outside world. 您不应该为父组件中的子组件元素编写CSS规则,因为Angular组件是一个自包含的实体,应该明确声明可用于外部世界的内容。 If child layout changes in the future, your styles for that child component elements scattered across other components' SCSS files could easily break, thus making your styling very fragile. 如果子布局将来发生变化,那么分散在其他组件的SCSS文件中的子组件元素的样式很容易破坏,从而使您的样式非常脆弱。 That's what ViewEncapsulation is for in the case of CSS. 这就是CSS的情况下ViewEncapsulation的用途。 Otherwise, it would be the same if you could assign values to private fields of some class from any other class in Object Oriented Programming. 否则,如果您可以从面向对象编程中的任何其他类为某些类的私有字段赋值,那么它将是相同的。

Therefore, what you should do is to define a set of classes you could apply to the child host element and implement how the child responds to them. 因此,您应该做的是定义一组可以应用于子宿主元素的类,并实现子代对它们的响应方式。

Technically, it could be done as follows: 从技术上讲,它可以如下完成:

// child.component.html:
<span class="label-1"></span>

// child.component.scss:
:host.child-color-black {
    .label-1 {
        color: black;
    }
}

:host.child-color-blue {
    .label-1 {
        color: blue ;
    }
}

// parent.component.html:
<child class="child-color-black"></child>
<child class="child-color-blue"></child>

In other words, you use :host pseudo-selector provided by Angular + set of CSS classes to define possible child styles in child component itself. 换句话说,您使用Angular + CSS类集提供的:host伪选择器来定义子组件本身中可能的子样式。 You then have the ability to trigger those styles from outside by applying pre-defined classes to the <child> host element. 然后,您可以通过将预定义的类应用于<child> host元素来从外部触发这些样式。

Today there are a couple of other possibilities: 今天还有其他几种可能性:

:host-context(.some-class-name) This lets you react on some outer class :host-context(.some-class-name)这使您可以对某些外部类做出反应

::ng-deep css-expression{ xx } This way you can define a class in the parent that will be available in it's children. :: ng-deep css-expression {xx}通过这种方式,您可以在父级中定义一个可在其子级中使用的类。


Example: 例:

parent.component.html parent.component.html

<app-button class="theme-blue"> my button </app-button>

button.component.css button.component.css

:host-context(.theme-blue) button {
   background-color: blue;
}

One may as well check out this very well guide: https://alligator.io/angular/styles-between-components-angular/ 有人可以查看这个非常好的指南: https//alligator.io/angular/styles-between-components-angular/

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM