如何在AngularJS中有条件地应用CSS样式?

Q1。 假设我想在主“删除”button被按下之前改变用户标记为删除的每个“项目”的外观。 (这种即时的视觉反馈应该消除对“你确定吗?”对话框的需求。)用户将检查checkbox以指示哪些项目应该被删除。 如果一个checkbox未选中,该项目应该恢复到正常的样子。

什么是应用或删除CSS样式的最佳方式?

Q2。 假设我想让每个用户个性化我的网站是如何呈现的。 例如,从一组固定的字体大小中select,允许用户可定义的前景色和背景色等。

什么是最好的方式来应用CSS样式的用户select/input?

Angular提供了许多内置的指令来有条件地/dynamic地操作CSS样式:

  • ng-class – 当一组CSS样式是静态/提前知道的时候使用
  • ng-style – 当你无法定义一个CSS类时使用,因为样式值可能会dynamic改变。 认为风格值的可编程控制。
  • ng-showng-hide – 如果你只需要显示或隐藏某些东西(修改CSS)
  • 如果您只需要检查单个条件(修改DOM),则使用版本1.1.5中的ng-if -new,而不是更详细的ng-switch;
  • ng-switch – 使用而不是使用几个互斥的ng-shows(修改DOM)
  • ng-disabledng-readonly – 用于限制表单元素的行为
  • ng-animate – 版本1.1.4中的新增function,用于添加CSS3转换/animation

正常的“angular度方法”涉及将模型/范围属性绑定到将接受用户input/操作(即,使用ng模型)的UI元素,然后将该模型属性与上述内置指令之一相关联。

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


Q1听起来像是ng-class的好例子 – CSS样式可以在一个类中被捕获。

ng-class接受一个“expression式”,它必须评估为以下之一:

  1. 一个空格分隔的类名string
  2. 一个类名的数组
  3. 类名的映射/对象为布尔值

假设您的项目使用ng-repeat在某些数组模型中显示,并且勾选某个项目的checkbox时,您想要应用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> 

上面,我们使用了ng-classexpression式types#3 – 类名称的映射/对象到布尔值。


Q2对于ng风格来说听起来像是一个很好的例子–CSS风格是dynamic的,所以我们不能为此定义一个类。

ng-style接受一个“expression式”,它必须评估为:

  1. CSS样式名称的映射/对象到CSS值

对于一个人为的例子,假设用户可以在背景颜色的texbox中input颜色名称(jQuery颜色select器会更好):

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

上述两个小提琴 。

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

当我有一个类已经应用到整个表(例如,应用于奇数行的颜色<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是我正在评估的,并且在每种情况下,我根据myvar值对每个<td>应用一个样式,覆盖整个表的CSS类应用的当前样式。

UPDATE

例如,如果您想在表中应用类,则在访问页面或其他情况下,可以使用以下结构:

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

基本上,我们需要激活一个ng类是应用的类和真或假的陈述。 真正应用这个类, 不。 所以在这里我们有两个页面路由和它们之间的OR检查,所以如果我们在/route_a 或者我们在route_b活动类将被应用。

这工作只是在右侧的逻辑函数返回true或false。

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

顺便说一句,我忘了给你的functionisActive():

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

更新

在这里,你有我发现真正有用的东西。 当您需要根据variables的值应用一个类时,例如,取决于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> 

从字体的图标真棒

当ng-class不能使用的时候(例如当样式化SVG时),这个效果很好:

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

(我认为你需要使用最新的不稳定Angular来使用ng-attr-,我目前在1.1.4上)

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

 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); } 

这个解决scheme为我做了窍门

 <a ng-style="{true: {paddingLeft: '25px'}, false: {}}[deleteTriggered]">...</a> 

看下面的例子

 <!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> 

另一个选项,当你需要一个或两个属性简单的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'; } }; 

你可以使用三元expression式。

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

从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 ... } 

还有一种(将来)有条件地应用风格的方式是有条件地创build范围风格

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

但是现在只有FireFox支持有范围的样式。

以及我会build议你检查你的控制器的条件与返回truefalse的函数。

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

并在你的控制器检查条件

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

还有一个选项,我最近发现有些人可能会觉得有用,因为它允许你在一个样式元素内改变一个CSS规则 – 从而避免重复使用一个angular度指令,比如ng-style,ng-class, ng-show,ng-hide,ng-animate等等。

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

 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); } }; }); 

有一点需要注意的是,如果CSS样式是破折号的,你必须删除它们。 所以如果你想设置background-color ,正确的方法是:

 ng-style="{backgroundColor:myColor}"