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

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

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

Q2。假设我想允许每个用户个性化我的站点的呈现方式。例如,从固定的字体大小中选择,允许用户自定义前景色和背景颜色等。

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

556574 次浏览

Angular提供了许多内置指令,用于有条件地/动态地操纵CSS样式:

  • ng-class -当CSS样式集是静态的/提前知道时使用
  • ng-style -当你不能定义CSS类时使用,因为样式值可能会动态变化。想想可编程控制的样式值。
  • ng-showng-hide -当你只需要显示或隐藏一些东西时使用(修改CSS)
  • ng-if - 1.1.5新版功能,如果你只需要检查单个条件,使用它来代替更冗长的ng-switch(修改DOM)
  • ng-switch -使用而不是使用几个互斥的ng-show(修改DOM)
  • ng-disabledng-readonly -用于限制表单元素的行为
  • ng-animate - 1.1.4新版功能,用于添加CSS3过渡/动画

正常的“Angular方式”包括将模型/作用域属性绑定到接受用户输入/操作的UI元素上(即使用ng-model),然后将该模型属性关联到上面提到的内置指令之一。

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

人力资源> < p > < Q1听起来像是ng-class的一个好例子——CSS样式可以在一个类中捕获

ng-class接受一个“表达式”,该表达式必须求值为以下之一:

  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>

上面,我们使用ng-class表达式类型#3 -类名到布尔值的映射/对象。

人力资源> < p > < Q2听起来像是ng-style的好例子——CSS样式是动态的,所以我们不能为此定义一个类

ng-style接受一个必须求值为的“表达式”:

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

举一个人为的例子,假设用户可以在文本框中输入一个颜色名称作为背景色(jQuery的颜色选择器会更好):

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

. 小提琴

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

当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

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

当我有一个类已经应用到整个表时,我发现在表格元素中应用类时出现了问题(例如,一个颜色应用到奇数行<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类为整个表应用的当前样式。

更新

如果你想将一个类应用到表中,例如,当访问一个页面或在其他情况下,你可以使用这个结构:

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

基本上,激活ng-class所需要的是要应用的类和true或false语句。真正的应用该类,而不应用该类。所以这里我们有两个页面路由的检查,它们之间有一个,所以如果我们在/route_a 我们在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>

字体太棒了中的图标

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

ng-style="{backgroundColor:myColor}"

还有一种(将来)有条件地应用样式的方法是有条件地创建有作用域的样式

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


</style>

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

这个解决办法对我很管用

<a ng-style="{true: {paddingLeft: '25px'}, false: {}}[deleteTriggered]">...</a>
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);
}

参见下面的示例

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

我建议你用返回真正的的函数检查控制器中的条件。

<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等。

这个选项使用了带有服务变量的服务,这些服务变量由控制器设置,并由一个我称之为“custom-style”的属性指令监视。此策略可以以许多不同的方式使用,并且我试图用小提琴提供一些一般性指导。

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样式时,另一个选择:

观点:

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

你可以使用三元表达式。有两种方法:

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

还是……

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

下面是我如何有条件地在禁用按钮上应用灰色文本样式

import { Component } from '@angular/core';


@Component({
selector: 'my-app',
styleUrls: [ './app.component.css' ],
template: `
<button
(click)='buttonClick1()'
[disabled] = "btnDisabled"
[ngStyle]="{'color': (btnDisabled)? 'gray': 'black'}">
\{\{btnText}}
</button>`
})
export class AppComponent  {
name = 'Angular';
btnText = 'Click me';
btnDisabled = false;
buttonClick1() {
this.btnDisabled = true;
this.btnText = 'you clicked me';
setTimeout(() => {
this.btnText = 'click me again';
this.btnDisabled = false
}, 5000);
}
}
下面是一个工作示例:
https://stackblitz.com/edit/example-conditional-disable-button?file=src%2Fapp%2Fapp.component.html < / p >