如何在主机元素中添加“类”?


187

我不知道如何添加到我的组件 <component></component> html(component.html)内动态属性。

我发现的唯一解决方案是通过“ ElementRef”本机元素修改项目。该解决方案似乎做起来应该很简单,有点复杂。

另一个问题是必须在组件范围之外定义CSS,这会破坏组件封装。

有没有更简单的解决方案?像<root [class]="..."> .... </ root>模板里面的东西。

Answers:


293
@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(); 
  }
}

柱塞示例

这样,您无需在组件外部添加CSS。像CSS

:host(.someClass) {
  background-color: red;
}

从组件内部工作,并且仅当someClass在host元素上设置了类时才应用选择器。


我必须执行someField = truein- ngOnInit()method而不是ngAfterViewInit()。我无法使其正常工作。
约翰,

在这里制作了一个叉子,显示了实际:host工作的零件。我在哪里可以了解有关@Component()装饰器中的主机参数的更多信息(语法对我来说并不明显,并且@Component文档没有太多解释)或了解有关您首选的HostBinding的信息(仅作为Interface列在Angular2网站?)
红豌豆(Red Pea

我不了解更好的文档,但这只是做事的另一种方式 @Input() @Output() @HostBinding() @HostListener() @ViewChild(ren)() @ContentChild(ren)()
君特Zöchbauer

1
将具有不同名称的吸气剂用于返回绑定值的主机绑定 @HostBinding('class.xxx') get xxxclass(){ return !this.someField;}
君特Zöchbauer

1
@YochaiAkoka不知道您指的是什么。我不知道这条规则。少即是多,因此,如果可以避免添加其他元素,则应避免添加。
君特Zöchbauer

184

Günter的回答很好(问题是要求动态类属性),但我想我只是为了完整性而添加...

如果您正在寻找一种快速干净的方法来将一个或多个静态类添加到组件的宿主元素(即,出于主题样式的目的),则可以执行以下操作:

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

1
为简单起见,喜欢它。但是在我的情况下,host元素封装了不同的属性,我们称它为组件组件ngcontent_template styleUrls中ngcontent_host模板中元素的任何属性,它们不会影响host元素,因为它们不会影响,只能影响模板元素;他们只会影响。我错了吗 有什么建议吗?我想我永远都可以转, let's call those , so if I put a style in the ngcontent_hostngcontent_templateViewEncapsulation.None
红豌豆

11
另一种方法是只跳过变量@HostBinding('class.someClass') true;。您甚至可以从组件扩展的任何类中执行此操作。
adamdport

3
要添加多个类,您可以托管:{'[class]':'“ class1 class2”'}
jbojcic

4
如果您使用host:{}变体,则可能要将设置use-host-property-decorator设置为falsein tslint.json。否则,您将收到IDE警告。@adamdport该方法不起作用(不再)。在我们的应用程序中使用Angular 5.2.2。
Ruud Voost

1
是我自己,还是旧方法似乎比新方法更好?我确定他们有充分的理由迁移,但是……
暗恋

12

您只需@HostBinding('class') class = 'someClass';@Component类中添加即可。

例:

@Component({
   selector: 'body',
   template: 'app-element'       
})
export class App implements OnInit {

  @HostBinding('class') class = 'someClass';

  constructor() {}      

  ngOnInit() {}
}

1
类名指令也可以使用,最好是避免使用class作为变量名(因为你可能会引用它,以后改变它)。范例:@HostBinding('className') myTheme = 'theme-dark';
CPHPython


0

这是我的操作方式(角度7):

在组件中,添加输入:

@Input() componentClass: string = '';

然后在组件的HTML模板中添加以下内容:

<div [ngClass]="componentClass">...</div>

最后在实例化组件的HTML模板中:

<root componentClass="someclass someotherclass">...</root>

免责声明:我是Angular的新手,所以我可能在这里很幸运!


2
稍微坏掉了:但是:这不会将CSS类添加到宿主元素-这是<root>标记的元素,而不是您添加到元素模板中的任何内容。
millimoose19年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.