2016-01-06 48 views
69

我不知道如何添加到我的组件<component></component>动态属性但在模板html(component.html)中。如何将“class”添加到主机元素?

我发现的唯一解决方案是通过“ElementRef”本地元素修改该项目。这个解决方案似乎有点复杂,要做一些应该很简单的事情。

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

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

+1

可能重复[如何通过打字稿类(angular2)更改主体类](http://stackoverflow.com/questions/34636661/how-do-i-change-the-body-class -via-a-typecript-class-angular2) –

+0

是的,这个解决方案也可以,但也太可怕了:)。另一个问题是,CSS必须在组件范围之外定义! (与ElementRef一样)。 – lascarayf

回答

140
@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。 CSS像从组件的内部与选择器

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

作品如果类someClass被设置在主机元件上仅适用。

+0

我不得不在'ngOnInit()' - 方法中执行'someField = true',而不是'ngAfterViewInit()'。否则我无法让它工作。 – John

+0

[Made a fork here](https://plnkr.co/edit/UsHyi78eza01N25ulxzA?p=preview)显示实际的':host'部分工作。我在哪里可以了解更多关于@Component()装饰器中的主机参数(语法对我来说不是很明显,[@Component文档没有解释太多](https://angular.io/docs/ts/latest /api/core/index/Component-decorator.html))或了解更多关于您首选的HostBinding(它只是[列为接口](https://angular.io/docs/ts/latest/api/core/index /HostBinding-interface.html)? –

+0

我不知道更好的文档,但它只是一种不同的方式来处理你可以用@Input()来执行的操作@ @Output()@@HostBinding() )''@HostListener()''@ViewChild(ren)()''@ContentChild(ren)()' –

79

君特的回答是伟大的(问题是要求动态类属性),但我想我会添加只是为了完整性...

如果你正在寻找一个快速和清洁的方式来增加一个或更静态类的组件的主元素(即,为主题造型的目的),你可以这样做:

@Component({ 
    selector: 'my-component', 
    template: 'app-element', 
    host: {'class': 'someClass1'} 
}) 
export class App implements OnInit { 
... 
} 

如果你在输入标签使用一个类,角将合并类,即,

<my-component class="someClass2"> 
    I have both someClass1 & someClass2 applied to me 
</my-component> 
+1

为了简单起见,喜欢这个。然而,在我的情况下,host元素被封装了一个不同的属性,我们把它称为'ngcontent_host',而不是我的模板中元素的任何属性'',所以我们调用那些'ngcontent_template',所以如果我把'styleUrls'我的组件,它们不会影响主机元素,因为它们不会影响'ngcontent_host',它们只能影响模板元素;它们只能影响'ngcontent_template'。我错了吗?对此有何建议?我想我总是可以变成'ViewEncapsulation.None' –

+0

糟糕,也许是因为Günter说:特殊的':主机'选择器。 [更多信息](https://angular.io/docs/ts/latest/guide/component-styles.html#-host) –

+0

非常简单和有效的解决方案,将类添加到组件的主机元素。我在我的应用程序中使用这个。谢谢分享! – Devner