Is it possible to add a dynamic class to host in A

2019-03-18 12:37发布

I know that in Angular2 I can add a class 'red' to a component's selector element by doing this:

@Component({
    selector: 'selector-el',
    host: {
        '[class.red]': 'true'
    },
    ...
})

I'm wondering whether there's a way to add a dynamic class to a host, similar to what you would do with NgClass (I know NgClass is not actually supported, I'm looking for possible solutions):

@Component({
    selector: 'selector-el',
    host: {
        '[NgClass]': 'colorClass'
    },
    ...
})
...
constructor(){
    this.colorClass = 'red';
}

6条回答
戒情不戒烟
2楼-- · 2019-03-18 12:51

The Renderers setElementClass can be used to add or remove an arbitrary class. For example md-[color] where color is provided by an input

<some-cmp [color]="red">
@Component({
// @Directive({
    selector: 'some-cmp',
    template: '...'
})
export class SomeComp {
    color_: string;

    @Input
    set color() {
        this.renderer.setElementClass(this.elementRef.nativeElement, 'md-' + this.color_, true);
    }

    get color(): string {
        return this.color_;
    }

    constructor(public elementRef: ElementRef, private renderer: Renderer){}
} 

See also looking for nativeElement.classList.add() alternative

查看更多
我命由我不由天
3楼-- · 2019-03-18 12:52
import {Component, HostBinding} from 'angular2/core';

@Component({
  (...)
}

export class MyComponent {
  @HostBinding('class') colorClass = 'red';
}
查看更多
聊天终结者
4楼-- · 2019-03-18 12:59

I have recently made a directive called <ng-host> (inspired by this issue), it will redirect every (non-structural) change to the component host element, usage:

@Component({
  template: `
    <ng-host [ngClass]="{foo: true, bar: false}"></ng-host>
    <p>Hello World!</p>
  `
})
class AppComponent { }

Online demo can be found here.

Supported usages defined here.

I have achieved this by the Directive as a Service pattern, namely manually providing NgClass and use it like (online demo)

Due to the DI mechanism, NgClass will get the ElementRef of current host element, the Self() modifier helps to guarantee it. So no need to create an instance by constructor, thus still under public API usage.

It could be more concise when combined with class inheritance, an example can be found at here.

查看更多
唯我独甜
5楼-- · 2019-03-18 13:09

You can use something like that:

@Directive({
  (...)
  host: {
    '[class.className]' : 'className', 
    '[class]' : 'classNames' 
  }
}
export class MyDirective {
  constructor() {
    this.className = true;
    this.classNames = 'class1 class2 class3';
  }
}
查看更多
对你真心纯属浪费
6楼-- · 2019-03-18 13:09

You can do the following:

import {Component} from "@angular/core"

@Component({
    selector: "[textbox]",
    host: {"class": "first-class secondClass ThirdClass AnYClaSs"},
    template: ...                                            
})
export class MyComponent { }

Which is imo way more straightforward than introducing a variable.
Should work in Angular2 rc5, rc6, rc7, final. May work in earlier versions, but didnt try it.

查看更多
疯言疯语
7楼-- · 2019-03-18 13:11

If you like to change it from outside you can combine @HostBinding and @Input():

@Component({
    selector: 'my-component',
    template: ``
})
export class MyComponent {
    @HostBinding('class.your-class') @Input() isSelected: boolean;
}
查看更多
登录 后发表回答