2012-12-11 39 views
290

第一季度。假设我想在主“删除”按钮被按下之前改变用户标记为删除的每个“项目”的外观。 (这种直接的视觉反馈应该消除对“你确定吗?”对话框的需求)。用户将检查复选框以指示哪些项目应该被删除。如果未勾选复选框,该项目应该恢复到正常状态。如何在AngularJS中有条件地应用CSS样式?第一季度:

什么是应用或删除CSS样式的最佳方式? Q2302。假设我想让每个用户个性化我的网站呈现方式。例如,从一组固定的字体大小的选择,允许用户自定义的前景色和背景色等

什么是应用CSS样式的用户选择/输入的最佳方式?

+0

有用的文章http://tech-blog.maddyzone.com/javascript/conditionally-apply-classes-in-angularjs –

回答

461

角度提供了大量的内置指令操纵CSS样式有条件/动态:

  • ng-class - 使用时设定的CSS样式是静态/事先已知的
  • ng-style - 当您无法定义CSS类时使用,因为样式值可能会动态更改。认为风格值的可编程控制。
  • ng-showng-hide - 使用,如果你只需要显示或隐藏着什么(修改CSS)
  • ng-if - 新的1.1.5版本,如果你改用了更详细的NG-开关只需要检查单个条件(修改DOM)
  • ng-switch - 使用的,而不是使用多个互相排斥的NG-显示(修改DOM)
  • ng-disabledng-readonly - 用于限制表单元素行为
  • ng-animate - 新的版本1.1.4,使用添加CSS3过渡/动画

正常“角办法”涉及搭售的典范/ scope属性添加到将接受用户输入/操作(即,使用ng-model)的UI元素,然后将该模型属性与上述内置指令之一相关联。

当用户更改UI时,Angular会自动更新页面上的相关元素。


Q1听起来像一个很好的理由纳克级 - 的CSS样式可以在一个类中被捕获。

纳克级接受一个“表达”必须评估为以下之一:

  1. 空间分隔的类名的字符串
  2. 类名称的数组
  3. 地图/类名称的对象为布尔值

假设您的项目使用ng-repeat在某些数组模型中显示,并且复选框为一个项目被选中要应用pending-delete类:

<div ng-repeat="item in items" ng-class="{'pending-delete': item.checked}"> 
    ... HTML to display the item ... 
    <input type="checkbox" ng-model="item.checked"> 
</div> 

前面,我们使用纳克级的表达式类型#3 - 类名布尔值的地图/对象。


Q2听起来像是ng样式的好例子 - CSS样式是动态的,所以我们不能为此定义类。

纳克式接受一个“表达”必须评估为:

  1. 一个地图/ CSS样式名称到CSS的对象值

对于人为的例子,假设用户可以在颜色名称键入到用于背景色texbox(一个jQuery颜色选择器将是好得多):

<div class="main-body" ng-style="{color: myColor}"> 
    ... 
    <input type="text" ng-model="myColor" placeholder="enter a color name"> 


Fiddle以上两者。

小提琴还包含ng-showng-hide的示例。如果选中复选框,除了背景颜色变成粉红色之外,还会显示一些文字。如果在文本框中输入“红色”,则div将隐藏。

+0

这个答案是太棒了!你是否愿意通过jsfiddle告诉我,如果点击事件改变/添加一个类不是点击元素的区域会有什么不同?在页面的其他地方说一个div。 – tehaaron

+0

这是有用的文章http://tech-blog.maddyzone.com/javascript/conditionally-apply-classes-in-angularjs –

+0

伟大的anwser。顺便说一句,你有没有尝试应用角度过滤器ng样式? –

33

这种运作良好,当NG-类不能使用(例如SVG造型时):

ng-attr-class="{{someBoolean && 'class-when-true' || 'class-when-false' }}" 

(我想你需要在最新的不稳定角用NG-attr-,我目前在1.1.4)

我发表了一篇关于使用AngularJS + SVG的文章。它讨论了这个问题和许多其他问题。 http://www.codeproject.com/Articles/709340/Implementing-a-Flowchart-with-SVG-and-AngularJS

+0

我在[1.1.4文档](http://code.angularjs.org/1.1.4/docs/api/)中没有看到ng-attr的提及 - 你有链接吗? –

+0

抱歉,没有链接。我通过遵循Angular论坛发现了它,尽管我不记得确切的网页抱歉。 –

+1

最新的文档(v1.2)在[directives page](http://docs.angularjs.org/guide/directive)上描述了'ng-attr-',section _ngAttr属性绑定_。 –

2

从AngularJS v1.2开始。0rc,ng-class甚至ng-attr-class失败,SVG元素(他们没有工作前,甚至与正常结合的类属性中)

具体来说,所有这些工作现在:

ng-class="current==this_element?'active':' ' " 
ng-attr-class="{{current==this_element?'active':' '}}" 
class="class1 class2 .... {{current==this_element?'active':''}}" 

作为一种变通方法,我已经使用

ng-attr-otherAttr="{{current==this_element?'active':''}}" 

,然后用风格

[otherAttr='active'] { 
    ... styles ... 
} 
100

我在应用元素中的类时发现了问题,当我将一个类应用于整个表时(例如,应用于奇数行的颜色<myClass tbody tr:nth-child(even) td>)。看来,当您使用开发人员工具检查元素时,element.style没有指定样式。因此,我没有使用ng-class,而是尝试使用ng-style,在这种情况下,新的CSS属性确实出现在element.style的内部。此代码为我的伟大工程:

<tr ng-repeat="element in collection"> 

    [...amazing code...] 

    <td ng-style="myvar === 0 && {'background-color': 'red'} || 
        myvar === 1 && {'background-color': 'green'} || 
        myvar === 2 && {'background-color': 'yellow'}">{{ myvar }}</td> 

    [...more amazing code...] 

</tr> 

MYVAR就是我评估,并在每一种情况下我样式应用到每个<td>根据MYVAR值,它重写CSS应用的当前形式整个表的类。

UPDATE

如果你想一类申请表例如,访问网页或在其他情况下,您可以使用此结构时:

<li ng-class="{ active: isActive('/route_a') || isActive('/route_b')}"> 

基本上,我们需要激活一个ng级是应用的类和一个真或假的陈述。 适用类和不适用。所以在这里,我们有网页的路线两次检查和它们之间的OR,所以如果我们在/route_aOR我们在route_b,该活跃类将被应用。

这只适用于在右侧返回true或false的逻辑功能。

所以在第一个例子中,ng-style受三条语句限制。如果它们都是假的,没有应用样式,但是按照我们的逻辑,至少有一个将被应用,所以,逻辑表达式将检查哪个变量比较是真的,并且因为非空数组总是为真,那将留下一个数组作为回报,并且只有一个是真实的,考虑到我们使用作为整个回应,剩余的样式将被应用。

对了,我忘了给你的函数isActive():

$rootScope.isActive = function(viewLocation) { 
    return viewLocation === $location.path(); 
}; 

新的更新

在这里你有什么事情,我觉得真正有用​​的。当你需要根据一个变量的值,适用于一类,例如,取决于div的内容的图标,可以使用下面的代码(在ng-repeat非常有用):

<i class="fa" ng-class="{ 'fa-github' : type === 0, 
          'fa-linkedin' : type === 1, 
          'fa-skype' : type === 2, 
          'fa-google' : type === 3 }"></i> 

Font Awesome

+0

什么是奇怪的语法,&&应该表示AND,就像在其他c语言中一样。 –

+3

@PizzaiolaGorgonzola &&的意思是AND和||确实意味着或。这是一个聪明的黑客使用短路逻辑几乎作为一种情况/开关语句... –

+0

感谢mit。我没有意识到这个细节。 – Timbergus

0

一件事图标看是 - 如果CSS样式有破折号 - 你必须删除它们。所以,如果你想设置background-color,正确的做法是:

通过有条件地创建范围的风格

<style scoped type="text/css" ng-if="..."> 

</style> 

但现在只有Firefox支持有条件申请风格

ng-style="{backgroundColor:myColor}" 
+4

不,你不需要。 ng-style =“{'background-color':myColor}”工作得很好。 – gerasalus

1

还有一个(在未来)的方式范围样式。

10

该解决方案的伎俩,我

<a ng-style="{true: {paddingLeft: '25px'}, false: {}}[deleteTriggered]">...</a> 
12
span class="circle circle-{{selectcss(document.Extension)}}"> 

和代码

$scope.selectcss = function (data) { 
    if (data == '.pdf') 
     return 'circle circle-pdf'; 
    else 
     return 'circle circle-small'; 
}; 

CSS

.circle-pdf { 
    width: 24px; 
    height: 24px; 
    font-size: 16px; 
    font-weight: 700; 
    padding-top: 3px; 
    -webkit-border-radius: 12px; 
    -moz-border-radius: 12px; 
    border-radius: 12px; 
    background-image: url(images/pdf_icon32.png); 
} 
+0

总是避免iF词 – LastTribunal

+0

@LastTribunal为什么? – iamserious

+0

我想鼓励避免直接使用class-attribute。这将覆盖此元素上其他插件所做的更改。 – SimonSimCity

6

请看下面的例子

<!DOCTYPE html> 
    <html ng-app> 
    <head> 
    <title>Demo Changing CSS Classes Conditionally with Angular</title> 
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.min.js"></script> 
    <script src="res/js/controllers.js"></script> 

    <style> 

    .checkboxList { 
     border:1px solid #000; 
     background-color:#fff; 
     color:#000; 
     width:300px; 
     height: 100px; 
     overflow-y: scroll; 
    } 

    .uncheckedClass { 
     background-color:#eeeeee; 
     color:black; 
    } 
    .checkedClass { 
     background-color:#3ab44a; 
     color:white; 
    } 
    </style> 

    </head> 
    <body ng-controller="TeamListCtrl"> 
    <b>Teams</b> 
    <div id="teamCheckboxList" class="checkboxList"> 

    <div class="uncheckedClass" ng-repeat="team in teams" ng-class="{'checkedClass': team.isChecked, 'uncheckedClass': !team.isChecked}"> 

    <label> 
    <input type="checkbox" ng-model="team.isChecked" /> 
    <span>{{team.name}}</span> 
    </label> 
    </div> 
    </div> 
    </body> 
    </html> 
1

很好,我建议你检查条件的控制器返回真正功能。

<div class="week-wrap" ng-class="{today: getTodayForHighLight(todayDate, day.date)}">{{day.date}}</div> 

,并在控制器检查车况

$scope.getTodayForHighLight = function(today, date){ 
    return (today == date); 
    } 
1

还有,我最近发现,因为它可以让你改变一个样式元素中的CSS规则,有些人可能会发现有用多了一个选择 - 从而避免了重复使用诸如ng-style,ng-class,ng-show,ng-hide,ng-animate等的角度指令的需要。

此选项使用服务变量,该变量由控制器设置,并由我称为“自定义样式”的属性指令监视。这个策略可以用很多不同的方式,我试图用这个fiddle提供一些一般的指导。

var app = angular.module('myApp', ['ui.bootstrap']); 
app.service('MainService', function(){ 
    var vm = this; 
}); 
app.controller('MainCtrl', function(MainService){ 
    var vm = this; 
    vm.ms = MainService; 
}); 
app.directive('customStyle', function(MainService){ 
    return { 
     restrict : 'A', 
     link : function(scope, element, attr){ 
      var style = angular.element('<style></style>'); 
      element.append(style); 
      scope.$watch(function(){ return MainService.theme; }, 
       function(){ 
        var css = ''; 
        angular.forEach(MainService.theme, function(selector, key){ 
         angular.forEach(MainService.theme[key], function(val, k){ 
          css += key + ' { '+k+' : '+val+'} '; 
         });       
        }); 
        style.html(css); 
       }, true); 
     } 
    }; 
}); 
5

另一种选择,当你需要的一个或两个属性的简单的CSS样式:

查看:

<tr ng-repeat="element in collection"> 
    [...amazing code...] 
    <td ng-style="{'background-color': getTrColor(element.myvar)}"> 
     {{ element.myvar }} 
    </td> 
    [...more amazing code...] 
</tr> 

控制器:

$scope.getTrColor = function (colorIndex) { 
    switch(colorIndex){ 
     case 0: return 'red'; 
     case 1: return 'green'; 
     default: return 'yellow'; 
    } 
}; 
4

您可以使用三元的表达。

<div ng-style="myVariable > 100 ? {'color': 'red'} : {'color': 'blue'}"></div>

+0

也许你会发现它更好:

Dudi

相关问题