Angular2中的ng-class

34

我正在使用Angular 2开发测试应用程序,目前遇到一个问题,即如何基于来自模型的列表添加类。

在Angular 1中可以这样做:

// model
$scope.myClasses = ['class1', 'class2', ...];

// view
... ng-class="myClasses" ...

在Angular 2中,到目前为止我所能做的就是:

// view
... [class.class1]="true" [class.class2]="true" ...
明显这种方法不太灵活,我相信一定有更好的方法。
然而,我也尝试过:
// model
class ... {
    private myClasses: any;
    constructor() {
        this.myClasses = ['class1', 'class2', ...];
    }

// view
... [class]="myClasses" ...

但是这并不起作用,我已经尝试过将myClasses作为单个类的字符串名称、字符串数组、具有类名键和值为true的对象、此类对象数组,但可悲的是,以上列出的所有方法都无法起作用。


1
您可以尝试通过注入 elementRef:ElementRef 并直接引用类列表来通过组件的类添加它们。或者可能在视图中使用您的最后一次尝试... this.classes = {'class1':true, 'class2':true} 并在您的视图中使用 [class]="classes" - Brocco
5个回答

39
根据NgClass API文档,Angular 2将接受一个字符串、一个数组或一个对象/映射作为表达式传递给NgClass。当然,你也可以指定一个返回其中之一的函数。
import {Component, CORE_DIRECTIVES} from 'angular2/angular2'

@Component({
  selector: 'my-app',
  directives: [CORE_DIRECTIVES],
  template: `
    <div>
      <h2>{{title}}</h2>
      <div ngClass="gray-border purple">string of classes</div>
      <div [ngClass]="'gray-border purple'">string of classes</div>
      <div [ngClass]="['gray-border', 'green']">array of classes</div>
      <div [ngClass]="{'gray-border': true, 'blue': true}">object/map of classes</div>
      <button [ngClass]="{active: isActive}" (click)="isActive = !isActive">Click me</button>
    </div>
  `,
  styles: [`
    .gray-border {  border: 1px solid gray; }
    .blue   { color: blue; }
    .green  { color: green; }
    .purple { color: purple; }
    .active { background-color: #f55; }
  `]
})
export class App {
  title = "Angular 2 - NgClass";
  isActive = false;
}

Plunker

如果您要传递一个字面字符串,请注意两种可选的语法:

<div ngClass="gray-border purple">string of classes</div>
<div [ngClass]="'gray-border purple'">string of classes</div>

我相信第一个只是第二个的语法糖。

引用文档中的一句话:

虽然 NgClass 指令可以解释求值为字符串、数组或对象的表达式,但基于对象的版本最常被使用,并且具有在模板中保留所有 CSS 类名的优点。


33

您必须在@View装饰器的directives属性中指定CSSClass。查看此plunk

@Component({
    selector: 'app',
})
@View({
    template: '<div [class]="classMap">Class Map</div>',
    directives: [CSSClass]
})
class App {
    constructor() {
        this.classMap = { 'class1': true, 'class2': false };

        setInterval(() => {
            this.classMap.class2 = !this.classMap.class2;
        }, 1000)
    }
}

更新

CSSClass 已在alpha-35版本中更名为 NgClass。请参考这个代码片段(plunk)

@Component({
  selector: 'app',
})
@View({
  directives: [NgClass],
  template: `
    <div [ng-class]="classMap">Class Map</div>
  `,
})
class App { /* ... */ }

2
CSSClass指令已更名为NgClass。 - Ilja Sucharev
1
ng-class已更改为ngClass。我猜想NgClass也不需要添加到提供程序中,但不确定。 - Günter Zöchbauer
beta.3现在在模板中使用[class],不需要指定指令。(我确定这不是第一个有这个改变的版本,只是我用过的最新版本。) - ps2goat
@EricMartinez 谢谢提醒!现在我没有时间做这个。稍后我会更新答案。 - alexpods

22

另一种方法 [使用三元运算符和插值]

(尽管Mark Rajcok列出了所有可能的ngClass方法,但您可以将其与三元运算符相结合,从而获得else条件)


模板

<div class="hard-coded-class {{classCondition ? 'c1 c2': 'c3 c4'}}">
    Conditional classes using <b>Ternary Operator</b>
</div>

或者使用带有ngClass三目运算符查看用法

TypeScript

export class App {
  this.classCondition = false;
}

结果

<div class="hard-coded-class c3 c4">
      Conditional classes using <b>Ternary Operator</b>
</div>

希望它能帮助到某人。


长时间以来一直在寻找/希望这个解决方案! - emvidi

2
使用typescript和Angular 2 beta,ngClass似乎无法工作。从API预览中可以看到 - https://angular.io/docs/ts/latest/api/common/NgClass-directive.html
template: '<div [ngClass]="classMap">Class Map</div>'

Google的示例提供了两个代码版本(我认为是Alpha和更新的Beta)。网站示例中的新语法似乎无法正常工作...有什么想法吗?
@View({
    template: `
        <div class="container questions">
            <div class="row formSection">
                 <h2>
                     <div [ngClass]="completed">completed</div>
                </h2>
                <questionSection></questionSection>
            </div>
        </div>
        `,
        directives: [NgClass, QuestionSection],
})

感谢您的回答,但是自从提出这个问题以来,规格变化了至少两次,据我所知。 - Marko Gresak

1

我曾尝试做类似的事情,我有一个菜单项列表,并希望为每个项目指定一个fontawesome类。这是我使它工作的方法。在我的typescript组件中,我有以下代码:

    export class AppCmp {
       menuItems = [
         {
           text: 'Editor',
           icon: 'fa fa-pencil'
         },
         {
           text: 'Account',
           icon: 'fa fa-user'
         },
         {
           text: 'Catalog',
           icon: 'fa fa-list'
         }
      ]
    }

然后在我的HTML中:
  <div *ngFor="#item of menuItems; #index = index">
        <i [attr.class]="item.icon"></i>
        <span>{{ item.text }}</span>
  </div>

这是 plunker,https://plnkr.co/edit/PIDRZsc7ZhISNgZzOWuY?p=preview 希望对你有帮助。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接