Cách tốt nhất để áp dụng có điều kiện một lớp học là gì?


1183

Hãy nói rằng bạn có một mảng được kết xuất trong một ulvới một liphần tử và một thuộc tính trên bộ điều khiển được gọi selectedIndex. Điều gì sẽ là cách tốt nhất để thêm một lớp vào lichỉ mục selectedIndextrong AngularJS?

Tôi hiện đang sao chép (bằng tay) limã và thêm lớp vào một trong các lithẻ và sử dụng ng-showng-hidechỉ hiển thị một licho mỗi chỉ mục.


2
Các câu trả lời cho câu hỏi này cho thấy có nhiều điều hơn về khuôn mẫu so với {{varname}}. Tôi có thể tìm tài liệu về những gì có nhiều hơn để tạo khuôn mẫu, chẳng hạn như toán tử ternary trong một vài hình thức khác nhau? docs.angularjs.org/guide/tem mẫu dường như không giải thích những gì cung cấp templating về điều kiện, vv ngoài {{varname.fieldname}}.
Christos Hayward

Điều này rất hữu ích đối với tôi hy vọng nó sẽ hiệu quả với bạn tech-blog.maddyzone.com/javascript/iêu
Rituraj ratan

Câu trả lời:


1384

Nếu bạn không muốn đặt tên lớp CSS vào Trình điều khiển như tôi thì đây là một mẹo cũ mà tôi sử dụng kể từ trước v1. Chúng ta có thể viết một biểu thức đánh giá trực tiếp tên lớp đã chọn , không cần chỉ thị tùy chỉnh:

ng:class="{true:'selected', false:''}[$index==selectedIndex]"

Xin lưu ý cú pháp cũ với dấu hai chấm.

Ngoài ra còn có một cách mới tốt hơn để áp dụng các lớp một cách có điều kiện, như:

ng-class="{selected: $index==selectedIndex}"

Angular hiện hỗ trợ các biểu thức trả về một đối tượng. Mỗi thuộc tính (tên) của đối tượng này hiện được coi là một tên lớp và được áp dụng tùy thuộc vào giá trị của nó.

Tuy nhiên những cách này không có chức năng như nhau. Đây là một ví dụ:

ng-class="{admin:'enabled', moderator:'disabled', '':'hidden'}[user.role]"

Do đó, chúng ta có thể sử dụng lại các lớp CSS hiện có bằng cách cơ bản ánh xạ một thuộc tính mô hình thành một tên lớp và đồng thời giữ các lớp CSS ra khỏi mã Trình điều khiển.


33
OP, đó có thể là cách tồi tệ hơn để thể hiện toán tử ternary mà tôi từng thấy. Bạn đã xem xét ($index==selectedIndex) ? 'selected' : ''chưa?
Malvolio

17
@Malvolio AFAIR, toán tử ternary không hoạt động trong các biểu thức góc trong v0.9.x. Đây là một hoặc ít hơn một chuyển đổi.
orcun

36
ng-class (kể từ 1/19/2012) hiện hỗ trợ một biểu thức phải ước tính 1) một chuỗi các tên lớp được phân tách bằng dấu cách hoặc 2) và mảng các tên lớp hoặc 3) một bản đồ / đối tượng của lớp tên cho các giá trị boolean. Vì vậy, sử dụng 3): ng-class = "{đã chọn: $ index == chọn Index}"
Mark Rajcok

2
Cảm ơn @Mark, BTW bây giờ tôi đã kiểm tra tôi có thể nói rằng phương pháp này đang hoạt động trong v1. Nó vẫn hữu ích trong một số trường hợp. Lưu ý rằng tên thuộc tính đối tượng (khóa) không nhất thiết là đúng hay sai, nó có thể là bất cứ thứ gì bạn muốn ánh xạ tới tên lớp.
orcun

6
Tôi chỉ muốn thêm, tôi đã gặp sự cố vì tôi đang sử dụng cú pháp như thế {classname: '$index === selectedIndex'} và nó không hoạt động. Khi tôi đẩy mọi thứ lại với nhau và sử dụng == thay vì ===, nó đã hoạt động. {classname: '$index==selectedIndex'}
Lucas

437

ng-class hỗ trợ một biểu thức phải đánh giá một trong hai

  1. Một chuỗi các tên lớp được phân tách bằng dấu cách hoặc
  2. Một mảng các tên lớp, hoặc
  3. Một bản đồ / đối tượng của các tên lớp thành các giá trị boolean.

Vì vậy, sử dụng mẫu 3) chúng ta có thể viết

ng-class="{'selected': $index==selectedIndex}"

Xem thêm Làm thế nào để tôi áp dụng có điều kiện các kiểu CSS trong AngularJS? cho một câu trả lời rộng hơn.


Cập nhật : Angular 1.1.5 đã thêm hỗ trợ cho toán tử ternary , vì vậy nếu cấu trúc đó quen thuộc hơn với bạn:

ng-class="($index==selectedIndex) ? 'selected' : ''"

2
+1 cho các toán tử ternary (và tôi cần một cái ngay bây giờ) nhưng 1.1. * Là một 'bản phát hành không ổn định' trong đó API có thể thay đổi mà không cần thông báo - tại thời điểm nhập. 1.0. * Là ổn định, vì vậy tôi sẽ thoải mái hơn khi dự án được triển khai vào tuần tới trong 6 tháng.
Dave Everitt

1
ng-class="{'selected': $index==selectedIndex}"làm việc cho tôi
knuhol 6/2/2015

160

Phương pháp yêu thích của tôi là sử dụng biểu thức ternary.

ng-class="condition ? 'trueClass' : 'falseClass'"

Lưu ý: Trong trường hợp bạn đang sử dụng phiên bản Angular cũ hơn, bạn nên sử dụng phiên bản này thay thế,

ng-class="condition && 'trueClass' || 'falseClass'"

2
Điều này đã giúp tôi viết biểu thức này : ng-class="property.name=='timestamp' ? 'property-timestamp' : 'property-'+{{$index}}". Không thể tìm ra cách nào khác.
dduft

Tôi thực sự không tìm thấy lý do tại sao modalFlag phạm vi của tôi không cập nhật - ng-class = "{'shut': modalFlag, 'open' :! ModalFlag}" Tôi đang cố gắng thêm hoặc đóng tùy thuộc vào biến / boolean - nếu có ai có thể giúp tôi sẽ rất biết ơn - cảm ơn bạn.
hạ cánh

Đây được giới thiệu là phiên bản 1.5. github.com/angular/angular.js/commit/ Mạnh
Mubashir Koul

55

Tôi sẽ thêm vào điều này, bởi vì một số trong những câu trả lời này dường như đã lỗi thời. Đây là cách tôi làm điều đó:

<class="ng-class:isSelected">

Trong đó 'isSelected' là biến javascript được xác định trong bộ điều khiển góc có phạm vi.


Để giải quyết cụ thể hơn câu hỏi của bạn, đây là cách bạn có thể tạo một danh sách với điều đó:

HTML

<div ng-controller="ListCtrl">  
    <li class="ng-class:item.isSelected" ng-repeat="item in list">   
       {{item.name}}
    </li>  
</div>


Mã não

function ListCtrl($scope) {    
    $scope.list = [  
        {"name": "Item 1", "isSelected": "active"},  
        {"name": "Item 2", "isSelected": ""}
    ]
}


Xem: http://jsfiddle.net/tTfWM/

Xem: http://docs.angularjs.org/api/ng.directive:ngClass


Có gì khác nhau giữa class = "ng-class: item.isSelected" và ng-class = "item.isSelected"
zloctb

Tò mò về việc sử dụng ng-class:classNamevs chỉ sử dụng class="{{className}}"?
Roi

48

Đây là một giải pháp đơn giản hơn nhiều:

function MyControl($scope){
    $scope.values = ["a","b","c","d","e","f"];
    $scope.selectedIndex = -1;
    
    $scope.toggleSelect = function(ind){
        if( ind === $scope.selectedIndex ){
            $scope.selectedIndex = -1;
        } else{
            $scope.selectedIndex = ind;
        }
    }
    
    $scope.getClass = function(ind){
        if( ind === $scope.selectedIndex ){
            return "selected";
        } else{
            return "";
        }
    }
       
    $scope.getButtonLabel = function(ind){
        if( ind === $scope.selectedIndex ){
            return "Deselect";
        } else{
            return "Select";
        }
    }
}
.selected {
    color:red;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.1/angular.min.js"></script>
<div ng-app ng-controller="MyControl">
    <ul>
        <li ng-class="getClass($index)" ng-repeat="value in values" >{{value}} <button ng-click="toggleSelect($index)">{{getButtonLabel($index)}}</button></li>
    </ul>
    <p>Selected: {{selectedIndex}}</p>
</div>


74
Tôi thực sự khuyên bạn nên để bộ điều khiển của bạn tránh xa các công cụ CSS. Đó là một con đường bạn không muốn đi xuống.
leviathan

1
Tên lớp thuộc về mẫu
Casey

5
Tại một số điểm, jsfiddle có thể bỏ lỡ để thanh toán hóa đơn của họ hoặc chọn chuyển sang tên miền khác hoặc những người có trách nhiệm bị giết bởi xe buýt (xem thêm Yếu tố xe buýt). Vì vậy, tôi có thể yêu cầu bạn giải thích những gì fiddle đó làm, trong câu trả lời của bạn? Đây cũng là kinh điển về tràn ngăn xếp.
Sebastian Mach

27

Tôi đã đối mặt với một vấn đề tương tự gần đây và quyết định chỉ tạo một bộ lọc có điều kiện:

  angular.module('myFilters', []).
    /**
     * "if" filter
     * Simple filter useful for conditionally applying CSS classes and decouple
     * view from controller 
     */
    filter('if', function() {
      return function(input, value) {
        if (typeof(input) === 'string') {
          input = [input, ''];
        }
        return value? input[0] : input[1];
      };
    });

Nó nhận một đối số duy nhất, đó là mảng 2 phần tử hoặc chuỗi, được biến thành một mảng được nối thêm một chuỗi rỗng làm thành phần thứ hai:

<li ng-repeat="item in products | filter:search | orderBy:orderProp |
  page:pageNum:pageLength" ng-class="'opened'|if:isOpen(item)">
  ...
</li>

1
tôi với tôi vừa tạo cho ví dụ một bộ lọc yesNo () trả về các lớp 'có' hoặc 'không' theo giá trị boolean 1 o 0:filter('yesNo', function() { return function(input) { // info('yesNo('+ input +')'); switch(input){ case '1': return ' yes '; break; default: return ' no '; break; } } });
svassr

1
ng-class có thể xử lý một ánh xạ / đối tượng của các tên lớp thành các giá trị boolean, vì vậy bạn chỉ cần viết như sau: ng-class = "{yes: some_boolean_expression, no: some_other_boolean_expression}" Eg, ng-class = "{yes: input , không :! input} "
Mark Rajcok

21

Nếu bạn muốn vượt ra ngoài đánh giá nhị phân và giữ CSS của bạn ra khỏi bộ điều khiển của bạn, bạn có thể triển khai một bộ lọc đơn giản để đánh giá đầu vào theo một đối tượng bản đồ:

angular.module('myApp.filters, [])
  .filter('switch', function () { 
      return function (input, map) {
          return map[input] || '';
      }; 
  });

Điều này cho phép bạn viết đánh dấu của bạn như thế này:

<div ng-class="muppets.star|switch:{'Kermit':'green', 'Miss Piggy': 'pink', 'Animal': 'loud'}">
    ...
</div>

Xin chào @Joe, có ý tưởng nào để xử lý các giá trị null không? Nếu tôi chuyển thành null trong đầu vào, nó sẽ không ánh xạ lớp của nó ...
dalcam

1
@ user1191559 - bạn có thể một mục 'mặc định' cho bản đồ, sau đó trả về giá trị đó nếu 'đầu vào' là null.
Joe Steele

17

Gần đây tôi đã làm điều đó:

<input type="password"  placeholder="Enter your password"
ng-class="{true: 'form-control isActive', false: 'isNotActive'}[isShowing]">

Các isShowinggiá trị là một giá trị được đặt trên bộ điều khiển của tôi mà được toggled với các bấm vào một nút và các bộ phận giữa ngoặc đơn được lớp tôi tạo ra trong file css của tôi.

EDIT: Tôi cũng muốn thêm rằng Codechool.com có ​​một khóa học miễn phí được tài trợ bởi google trên AngularJS, vượt qua tất cả những thứ này và sau đó là một số. Không cần phải trả tiền cho bất cứ điều gì, chỉ cần đăng ký một tài khoản và bắt đầu đi! Tốt nhất của may mắn cho tất cả các bạn!


Bạn có thể cung cấp một fiddle hoặc nhiều mã ở đây? Là isShowingmột mảng trong bộ điều khiển sau đó?
Kyle Pennell

Tôi đoán là một boolean
Mirko

15

Toán tử ternary vừa được thêm vào trình phân tích cú pháp góc trong 1.1.5 .

Vì vậy, cách đơn giản nhất để làm điều này là bây giờ:

ng:class="($index==selectedIndex)? 'selected' : ''"

Ngoài ra : class="otherClass ng-class:($index==selectedIndex)? 'selected' : '';".
peter

11

Chúng ta có thể tạo một hàm để quản lý lớp trả về với điều kiện

nhập mô tả hình ảnh ở đây

<script>
    angular.module('myapp', [])
            .controller('ExampleController', ['$scope', function ($scope) {
                $scope.MyColors = ['It is Red', 'It is Yellow', 'It is Blue', 'It is Green', 'It is Gray'];
                $scope.getClass = function (strValue) {
                    switch(strValue) {
                        case "It is Red":return "Red";break;
                        case "It is Yellow":return "Yellow";break;
                        case "It is Blue":return "Blue";break;
                        case "It is Green":return "Green";break;
                        case "It is Gray":return "Gray";break;
                    }
                }
        }]);
</script>

Và sau đó

<body ng-app="myapp" ng-controller="ExampleController">

<h2>AngularJS ng-class if example</h2>
<ul >
    <li ng-repeat="icolor in MyColors" >
        <p ng-class="[getClass(icolor), 'b']">{{icolor}}</p>
    </li>
</ul>
<hr/>
<p>Other way using : ng-class="{'class1' : expression1, 'class2' : expression2,'class3':expression2,...}"</p>
<ul>
    <li ng-repeat="icolor in MyColors">
        <p ng-class="{'Red':icolor=='It is Red','Yellow':icolor=='It is Yellow','Blue':icolor=='It is Blue','Green':icolor=='It is Green','Gray':icolor=='It is Gray'}" class="b">{{icolor}}</p>
    </li>
</ul>

Bạn có thể tham khảo trang mã đầy đủ tại ng-class nếu ví dụ


9

Tôi chưa quen với Angular nhưng đã tìm thấy điều này để giải quyết vấn đề của mình:

<i class="icon-download" ng-click="showDetails = ! showDetails" ng-class="{'icon-upload': showDetails}"></i>

Điều này sẽ áp dụng một cách có điều kiện một lớp dựa trên một var. Nó bắt đầu với một biểu tượng tải xuống làm mặc định, sử dụng ng-class, tôi kiểm tra trạng thái showDetailsnếu true/falsevà áp dụng tải lên biểu tượng lớp . Nó hoạt động rất tốt.

Hy vọng nó giúp.


9

Công việc này như một cái duyên vậy ;)

<ul class="nav nav-pills" ng-init="selectedType = 'return'">
    <li role="presentation" ng-class="{'active':selectedType === 'return'}"
        ng-click="selectedType = 'return'"><a href="#return">return

    </a></li>
    <li role="presentation" ng-class="{'active':selectedType === 'oneway'}"
        ng-click="selectedType = 'oneway'"><a href="#oneway">oneway
    </a></li>
</ul>

5

Điều này có thể sẽ bị hạ cấp xuống lãng quên, nhưng đây là cách tôi sử dụng các toán tử tạm thời của 1.1.5 để chuyển đổi các lớp tùy thuộc vào việc một hàng trong bảng là đầu tiên, giữa hay cuối - trừ khi chỉ có một hàng trong bảng:

<span class="attribute-row" ng-class="(restaurant.Attributes.length === 1) || ($first ? 'attribute-first-row': false || $middle ? 'attribute-middle-row': false || $last ? 'attribute-last-row': false)">
</span>

5

Đây là trong công việc của tôi nhiều thẩm phán có điều kiện:

<li ng-repeat='eOption in exam.examOptions' ng-class="exam.examTitle.ANSWER_COM==exam.examTitle.RIGHT_ANSWER?(eOption.eoSequence==exam.examTitle.ANSWER_COM?'right':''):eOption.eoSequence==exam.examTitle.ANSWER_COM?'wrong':eOption.eoSequence==exam.examTitle.RIGHT_ANSWER?'right':''">
  <strong>{{eOption.eoSequence}}</strong> &nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;&nbsp;
  <span ng-bind-html="eOption.eoName | to_trusted">2020 元</span>
</li>

4

Đây là một tùy chọn khác hoạt động tốt khi không thể sử dụng ng-class (ví dụ: khi tạo kiểu SVG):

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

(Tôi nghĩ rằng bạn cần phải có Angular không ổn định mới nhất để sử dụng ng-attr-, tôi hiện đang ở 1.1.4)


4

tôi cũng sẽ đề nghị bạn kiểm tra điều kiện trong bộ điều khiển của bạn với một hàm trả về đúng hay sai .

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

và trong bộ điều khiển của bạn kiểm tra điều kiện

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

4

một phần

  <div class="col-md-4 text-right">
      <a ng-class="campaign_range === 'thismonth' ? 'btn btn-blue' :  'btn btn-link'" href="#" ng-click='change_range("thismonth")'>This Month</a>
      <a ng-class="campaign_range === 'all' ? 'btn btn-blue' :  'btn btn-link'" href="#" ng-click='change_range("all")'>All Time</a>
  </div>

bộ điều khiển

  $scope.campaign_range = "all";
  $scope.change_range = function(range) { 
        if (range === "all")
        {
            $scope.campaign_range = "all"
        }
        else
        {  
            $scope.campaign_range = "thismonth"
        }
  };

3

Nếu bạn đang sử dụng góc trước v1.1.5 (nghĩa là không có toán tử ternary) và bạn vẫn muốn một cách tương đương để đặt giá trị trong cả hai điều kiện, bạn có thể làm một cái gì đó như thế này:

ng-class="{'class1':item.isReadOnly == false, 'class2':item.isReadOnly == true}"

3

Nếu bạn có một lớp chung được áp dụng cho nhiều yếu tố, bạn có thể tạo một lệnh tùy chỉnh sẽ thêm lớp đó như ng-show / ng-hide.

Lệnh này sẽ thêm lớp 'hoạt động' vào nút nếu nó được bấm

module.directive('ngActive',  ['$animate', function($animate) {
  return function(scope, element, attr) {
    scope.$watch(attr.ngActive, function ngActiveWatchAction(value){
      $animate[value ? 'addClass' : 'removeClass'](element, 'active');
    });
  };
}]);

Thêm thông tin


3

Chỉ cần thêm một cái gì đó làm việc cho tôi ngày hôm nay, sau khi tìm kiếm nhiều ...

<div class="form-group" ng-class="{true: 'has-error'}[ctrl.submitted && myForm.myField.$error.required]">

Hy vọng điều này sẽ giúp phát triển thành công của bạn.

=)

Cú pháp biểu hiện không có giấy tờ: Liên kết trang web tuyệt vời ... =)


Kiểm tra câu trả lời được chấp nhận. Nó đang làm điều tương tự và đưa ra nhiều ví dụ.
tôn trọng TheCode

3

Kiểm tra này .

if|elseTuyên bố AngularJS khét tiếng !!!
Khi tôi bắt đầu sử dụng Angularjs, tôi hơi ngạc nhiên rằng tôi không thể tìm thấy một câu lệnh if / other.

Vì vậy, tôi đã làm việc trên một dự án và tôi nhận thấy rằng khi sử dụng câu lệnh if / other, điều kiện hiển thị trong khi tải. Bạn có thể sử dụng ng-cloak để sửa lỗi này.

<div class="ng-cloak">
 <p ng-show="statement">Show this line</span>
 <p ng-hide="statement">Show this line instead</span>
</div>

.ng-cloak { display: none }

Cảm ơn amadou


0

Bạn có thể sử dụng gói npm này . Nó xử lý tất cả mọi thứ và có các tùy chọn cho các lớp tĩnh và có điều kiện dựa trên một biến hoặc một hàm.

// Support for string arguments
getClassNames('class1', 'class2');

// support for Object
getClassNames({class1: true, class2 : false});

// support for all type of data
getClassNames('class1', 'class2', ['class3', 'class4'], { 
    class5 : function() { return false; },
    class6 : function() { return true; }
});

<div className={getClassNames({class1: true, class2 : false})} />
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.