提问



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


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


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


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

最佳参考


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



  • ng-class - 在CSS样式集静态/提前知道时使用

  • ng-style - 在无法定义CSS类时使用,因为样式值可能会动态更改。请考虑样式值的可编程控制。

  • ng-show ng-hide - 如果您只需要显示或隐藏某些内容(修改CSS),请使用

  • ng-if - 版本1.1.5中的新增功能,如果您只需要检查单个条件(修改DOM),请使用代替更详细的ng-switch

  • ng-switch - 使用而非使用多个互斥的ng-shows(修改DOM)

  • ng-disabled ng-readonly - 用于限制表单元素行为

  • ng-animate - 版本1.1.4中的新功能,用于添加CSS3过渡/动画



正常的Angular方式涉及将模型/范围属性绑定到将接受用户输入/操作(即,使用ng-model)的UI元素,然后将该模型属性与上述内置指令之一相关联。 [39] [40] [41] [42] [43] [44] [45] [46] [47]


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




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 - 类名的映射/对象到布尔值。




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


ng-style 接受必须评估为的表达式:



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



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


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




上述两者的小提琴。[48]


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

其它参考1


当我已经将一个类应用于整个表时(例如,应用于奇数行<myClass tbody tr:nth-child(even) td>的颜色),我在 table 元素中应用类时发现了问题。看来,当您使用开发人员工具检查元素时,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语句。 True 适用于该类,而 false 则不会。所以这里我们对页面路由进行了两次检查,并且它们之间有一个 OR ,所以如果我们在/route_a OR ,我们在route_b中,将应用Activity类。


这只是在右边有一个返回true或false的逻辑函数。


因此,在第一个示例中, ng-style 受三个语句的限制。如果所有这些都是假的,则不应用样式,但是遵循我们的逻辑,将至少应用一个,因此,逻辑表达式将检查哪个变量比较为真,并且因为非空数组始终为真,所以将数组作为返回并且只有一个为true,考虑到我们使用 OR 作为整个响应,将应用剩余的样式。


顺便说一句,我忘了给你功能isActive():


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


NEW UPDATE


在这里你有一些我觉得非常有用的东西。当您需要根据变量的值应用类时,例如,取决于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的图标[49]


其它参考2


当不能使用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[50]

其它参考3


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

其它参考4


这个解决方案对我有用


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

其它参考5


请参阅以下示例


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

其它参考6


当您需要一个或两个属性的简单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';
    }
};

其它参考7


您可以使用三元表达式。有两种方法可以做到这一点:


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


要么...


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

其它参考8


从AngularJS v1.2.0rc开始,ng-class甚至ng-attr-class都失败了SVG元素(它们确实更早,即使在class属性中有正常绑定)


具体来说,现在这些都不起作用:


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

其它参考9


有条件地应用样式的另一种(将来)方式是通过有条件地创建范围样式


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

</style>


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

其它参考10


好吧,我建议您使用返回 true false 的函数检查控制器中的条件。


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


并在您的控制器中检查条件


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

其它参考11


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


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


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

其它参考12


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


ng-style="{backgroundColor:myColor}"