@HostBinding与angular2中的变量类

时间:2016-02-03 04:44:12

标签: angular

我有这个代码在主机上设置一个类:

@HostBinding('class.fixed') true;

我想做的是让它成为我可以修改的变量类。 我怎么能这样做?

8 个答案:

答案 0 :(得分:55)

这不可变。

您可以做的是直接绑定到类属性

@HostBinding('class') classes = 'class1 class2 class3';

答案 1 :(得分:26)

如果您的课程数量有限,您可以有条件地添加每个课程:

@HostBinding('class.c1') get c1 () { return this.useC1; } 
@HostBinding('class.c2') get c2 () { return this.useC2; }

请注意,.c1.c2需要在组件外定义。

Plunker

答案 2 :(得分:11)

我必须与其他答案相矛盾,没有理由说绑定class.className不应该起作用。实际上,以下格式正常工作:

@HostBinding('class.className') variableName = true;

如果它不适用于你的情况,你可能需要在CSS类中添加一个范围(你可以看到讨论here)。

问题是HostBinding只能看到主机范围,因此如果您要在{{1}的元数据中定义某种样式你需要指定css属于主机范围。

您只需在CSS规则之前添加Component即可轻松指定主机范围:

:host

取代

:host.className {
  /* Your CSS here */
}

如果你愿意,我创建了一个可以看到clicking here

的工作Plunker

答案 3 :(得分:5)

如果已经有一些类名绑定到变量,Günter的答案确实没有用。

变量字符串类名与布尔样式预定义类名组合的好方法是使用classnames npm包。

将它与@HostBinding和setter函数一起使用可获得惊人的效果:

import * as classNames from 'classnames';

(...)

@HostBinding('class') get classes(): string {
  return classNames(this.getDynamicClassName(), {
    'is-open': this.isOpen,
    'has-children': this.hasChildren
  });
}

答案 4 :(得分:2)

您可以使用class创建一些独立的指令。

例如:我的页面中有一个按钮,可能会指出:defaultprimarydangerfluid。按钮可以有许多不同的状态,但由于代码量很大,我会告诉你三种状态。所以让我们开始吧!

<强> button.ts

//default button

@Directive({
    selector: '[appButtonDefault]'
})
export class ButtonDefaultDirective {

    // the name of the field is not important
    // if you put this directive to element, 
    // this element will have the class called 'button--default'

    @HostBinding("class.button--default")
    private defaultClass: boolean = true;
}


//primary button

@Directive({
    selector: '[appButtonPrimary]'
})
export class ButtonPrimaryDirective {

    // the name of the field is not important
    // if you put this directive to element, 
    // this element will have the class called 'button--primary'

    @HostBinding("class.button--primary")
    private primaryClass: boolean = true;
}


// danger button

@Directive({
    selector: '[appButtonDanger]'
})
export class ButtonDangerDirective {

    // the name of the field is not important
    // if you put this directive to element, 
    // this element will have the class called 'button--primary'

    @HostBinding("class.button--danger")
    private dangerClass: boolean = true;
}

@Directive({
    selector: '[appButtonFluid]'
})
export class ButtonFluidDirective {

    // the name of the field is not important
    // if you put this directive to element, 
    // this element will have the class called 'button--primary'

    @HostBinding("class.button--fluid")
    private fluidClass: boolean = true;
}


// you need to also create a component class,
// that import styles for this button
@Component({
    //just put created selectors in your directives
    selector: `[appButtonDefault], [appButtonPrimary], 
               [appButtonDanger], [appButtonFluid]`,
    styleUrls: ['<-- enter link to your button styles -->'],

    // it is required, because the content of <button> tag will disappear
    template: "<ng-content></ng-content>" 
})
export class ButtonComponent {}


// you don't have to do it, but I prefet to do it

@NgModule({
    declarations: [
        ButtonDefaultDirective,
        ButtonPrimaryDirective,
        ButtonDangerDirective,
        ButtonFluidDirective,
        ButtonComponent
    ],
    exports: [
        ButtonDefaultDirective,
        ButtonPrimaryDirective,
        ButtonDangerDirective,
        ButtonFluidDirective,
        ButtonComponent
    ]
})
export class ButtonModule {}

不要忘记将ButtonModule导入您的app.module.ts文件。这非常重要。

<强> app.component.html

<!-- This button will have the class 'button--default' -->
<button appButtonDefault>Default button</button>

<!-- But this button will have the class 'button--primary button--fluid' -->
<button appButtonPrimary appButtonFluid>Primary and fluid</button>

我希望它有所帮助。

答案 5 :(得分:0)

@Input()
  class = '';

@HostBinding('attr.class')
get btnClasses() {
return [
    'btn',
    this.someClassAsString,
    this.enableLight ? 'btn-secondary-light' : '',
    this.class,
].filter(Boolean).join(' ');
};

您可以使用输入劫持class属性,并在主机绑定中添加所需的内容

答案 6 :(得分:0)

您可以使用Angular host@Component装饰器的@Directive属性进行此操作。然后,您可以将其绑定到返回所需类的getter返回字符串。

See Angular documentation here.

这是我的工作代码,用于根据Input size枚举分配Bootstrap列类。请注意,host绑定的@Component部分指向hostClass,这是我的组件中的吸气剂。

@Component({
    selector: 'app-form-field',
    templateUrl: './form-field.component.html',
    styleUrls: ['./form-field.component.scss'],
    host: {'[class]': 'hostClass'}
})
export class FormFieldComponent {
    @Input: size: ComponentSize;

    get hostClass(): string {
        switch (this.size) {
            case (ContentSize.OneThird): {
                return 'col-4 col-xl-2';
            }
            case (ContentSize.Half): {
                return 'col-6 col-xl-3';
            }
            case (ContentSize.TwoThirds): {
                return 'col-8 col-xl-4';
            }
            case (ContentSize.OnePointFive): {
                return 'col-9';
            }
            case (ContentSize.Double): {
                return 'col-12';
            }
        }
        return 'col-md-6';
    }
}

答案 7 :(得分:0)

已经有很多答案,但没有一个提到NgClass。 在我看来,最可靠和一致的方法是扩展 NgClass,因为它提供了我们开箱即用所需的一切:

@Directive({ selector: '[myDirective]'})
export class MyDirective extends NgClass {
  constructor(
    _iterableDiffers: IterableDiffers,
    _keyValueDiffers: KeyValueDiffers,
    _ngEl: ElementRef,
    _renderer: Renderer2
  ) {
    super(_iterableDiffers, _keyValueDiffers, _ngEl, _renderer);
  }

  setClass() {
    this.ngClass = {
      underline: true,
      bold: true,
      italic: true,
      pretty: false
    };

    // or
    this.ngClass = ['asd', 'abc', 'def'];

    // or 
    this.ngClass = 'foo';
  }
}