如何将“类”添加到宿主元素?
Posted
技术标签:
【中文标题】如何将“类”添加到宿主元素?【英文标题】:How to add "class" to host element? 【发布时间】:2016-04-11 00:35:41 【问题描述】:我不知道如何在我的组件<component></component>
中添加一个动态的class 属性,但在模板html (component.html) 中。
我找到的唯一解决方案是通过“ElementRef”原生元素修改项目。这个解决方案似乎有点复杂,做一些应该很简单的事情。
另一个问题是 CSS 必须在组件范围之外定义,破坏了组件封装。
有没有更简单的解决方案?模板中的 <root [class]="..."> .... </ root>
之类的东西。
【问题讨论】:
【参考方案1】:这就是我所做的:
import Component, Attribute, HostBinding from "@angular/core";
@Component(
selector: "selector-el",
template: ...
)
export class MyComponent
@HostBinding('class') get classAttribute(): string
let defaultClasses = 'selector-el-class';
return defaultClasses + ' ' + this.classNames;
constructor(
@Attribute('class') public classNames: string
)
【讨论】:
您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center。【参考方案2】:除了@JoshuaDavid 的回答,还有另一种定义静态类的方法,当我尝试时它适用于角度 v8(可能也适用于旧版本):
@Component(
selector: "my-component.someClass1.someClass2",
...
)
这将产生以下输出:
<my-component class="someClass1 someClass2">
...
</my-component>
你也可以这样使用:
@Component(
selector: ".someClass1.someClass2",
...
)
这将产生以下输出:
<div class="someClass1 someClass2">
...
</div>
【讨论】:
如果我指定selector: "my-component.someClass1.someClass2",
,那么我必须在 HTML 中使用选择器,例如 这样你就不需要在组件之外添加CSS了:
@Component(
selector: 'body',
template: 'app-element',
// prefer decorators (see below)
// host: '[class.someClass]':'someField'
)
export class App implements OnInit
constructor(private cdRef:ChangeDetectorRef)
someField: boolean = false;
// alternatively also the host parameter in the @Component()` decorator can be used
@HostBinding('class.someClass') someField: boolean = false;
ngOnInit()
this.someField = true; // set class `someClass` on `<body>`
//this.cdRef.detectChanges();
Plunker example
这个 CSS 是在组件内部定义的,只有当 someClass
类设置在宿主元素上时才会应用选择器(从外部):
:host(.someClass)
background-color: red;
【讨论】:
我必须在ngOnInit()
-方法中使用someField = true
而不是ngAfterViewInit()
。否则我无法让它工作。
Made a fork here 显示实际的:host
部分工作。我在哪里可以了解更多关于 @Component() 装饰器中的主机参数(语法对我来说并不明显,以及 @Component documentation doesn't explain very much)或了解更多关于您首选的 HostBinding(它只是 Angular2 站点上的 listed as an Interface?)
我不知道更好的文档,但这只是用 @Input()
@Output()
@HostBinding()
@HostListener()
@ViewChild(ren)()
@ContentChild(ren)()
做的另一种方式>
对主机绑定使用不同名称的getter,返回反转值@HostBinding('class.xxx') get xxxclass() return !this.someField;
@YochaiAkoka 不确定您指的是什么。我不知道这个规则。少即是多,所以如果你能避免添加额外的元素,那么你应该避免它。【参考方案4】:
另一个问题是 CSS 必须在组件范围之外定义,破坏了组件封装
这不是真的。使用 scss (SASS),您可以轻松地设置组件(本身;主机)的样式:
:host
display: block;
position: absolute;
width: 100%;
height: 100%;
pointer-events: none;
visibility: hidden;
&.someClass
visibility: visible;
这样封装是“完整的”。
【讨论】:
由于其他答案有不同的方式为您的组件设置类,如果您使用这种方式,您可以将您的类设置为组件上的类。因此,对于此答案中的示例,它将是:对于多类的情况,就像上面提到的@jbojcic,你可以使用:
主机:类:'A B C'
【讨论】:
【参考方案6】:您可以在 @Component 类中简单地添加@HostBinding('class') class = 'someClass';
。
例子:
@Component(
selector: 'body',
template: 'app-element'
)
export class App implements OnInit
@HostBinding('class') class = 'someClass';
constructor()
ngOnInit()
【讨论】:
className directive 也可以使用,最好避免使用class
作为变量名(因为您可能会引用它并在以后更改它)。示例:@HostBinding('className') myTheme = 'theme-dark';
.
我肯定会避免将变量命名为“类”。一些包将其命名为“klass”或“cssClass”【参考方案7】:
如果你想为你的宿主元素添加一个动态类,你可以将你的 HostBinding
与一个 getter 结合起来
@HostBinding('class') get class()
return aComponentVariable
Stackblitz 演示,https://stackblitz.com/edit/angular-dynamic-hostbinding
【讨论】:
【参考方案8】:Günter 的回答很棒(问题是要求 dynamic 类属性),但我想我只是为了完整性而添加...
如果您正在寻找一种快速而简洁的方法来将一个或多个 static 类添加到组件的宿主元素(即,出于主题样式目的),您可以这样做:
@Component(
selector: 'my-component',
template: 'app-element',
host: 'class': 'someClass1'
)
export class App implements OnInit
...
如果你在 entry 标签上使用了一个类,Angular 会合并这些类,即,
<my-component class="someClass2">
I have both someClass1 & someClass2 applied to me
</my-component>
【讨论】:
为了简单起见喜欢这个。但是在我的情况下,主机元素被封装了一个不同的属性,我们称它为ngcontent_host
,而不是我的组件的模板, let's call those
ngcontent_template, so if I put a style in the
styleUrls`中的元素上的任何属性,它们不会影响主机元素,因为它们不会影响 ngcontent_host
,它们只能影响模板元素;它们只能影响ngcontent_template
。我弄错了吗?对此有何建议?我想我总是可以转ViewEncapsulation.None
另一种方法是跳过变量@HostBinding('class.someClass') true;
。您甚至可以从您的组件扩展的任何类中执行此操作。
添加多个类你可以做 host: '[class]': '"class1 class2"'
如果您使用主机:
变体,您可能希望在tslint.json
中将use-host-property-decorator
设置设置为false
。否则,您将收到 IDE 警告。 @adamdport 该方法不起作用(不再)。在我们的应用中使用 Angular 5.2.2。
@adamdport 您的回答将创建一个名为“true”的变量,类型为“any”。不确定这是否是您的意图?【参考方案9】:
我是这样做的(Angular 7):
在组件中,添加一个输入:
@Input() componentClass: string = '';
然后在组件的 HTML 模板中添加如下内容:
<div [ngClass]="componentClass">...</div>
最后在您实例化组件的 HTML 模板中:
<root componentClass="someclass someotherclass">...</root>
免责声明:我对 Angular 还很陌生,所以我可能只是在这里走运!
【讨论】:
以上是关于如何将“类”添加到宿主元素?的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 @hostbinding 为 Angular 2 中的宿主元素提供类
如何将类添加到由 appendChild 创建的元素 [重复]
如何将动态 TailwindCSS 类添加到 React 中的 DOM 元素