วิธีที่ดีที่สุดในการสมัครเรียนแบบมีเงื่อนไขคืออะไร?


1183

ช่วยบอกว่าคุณมีอาร์เรย์ที่แสดงผลในulมีสระสำหรับแต่ละองค์ประกอบและคุณสมบัติในตัวควบคุมที่เรียกว่าli selectedIndexอะไรจะเป็นวิธีที่ดีที่สุดในการเพิ่มคลาสเข้าliกับดัชนีselectedIndexใน AngularJS

ขณะนี้ฉันกำลังทำสำเนา (ด้วยมือ) liโค้ดและเพิ่มคลาสให้กับหนึ่งในliแท็กและใช้ng-showและng-hideเพื่อแสดงเพียงหนึ่งรายการliต่อดัชนี


2
คำตอบสำหรับคำถามนี้แสดงว่ามีเทมเพลตมากกว่า {{varname}} ฉันจะหาเอกสารว่ามีเทมเพลตอะไรอีกมากมายเช่นผู้ประกอบการไตรภาคในรูปแบบที่แตกต่างกันสองแบบ docs.angularjs.org/guide/templatesดูเหมือนจะไม่อธิบายว่าเทมเพลตมีอะไรบ้างในแง่ของเงื่อนไขและอื่น ๆ นอกเหนือจาก {{varname.fieldname}}
Christos Hayward

นี่คือข้าวต้มที่มีประโยชน์สำหรับฉันหวังว่ามันจะทำงานให้คุณtech-blog.maddyzone.com/javascript/…
Rituraj ratan

คำตอบ:


1384

หากคุณไม่ต้องการใส่ชื่อคลาส CSS ลงใน Controller อย่างที่ฉันทำนี่เป็นกลอุบายเก่า ๆ ที่ฉันใช้มาตั้งแต่ pre-v1 วัน เราสามารถเขียนนิพจน์ที่ประเมินโดยตรงกับชื่อคลาสที่เลือกไม่จำเป็นต้องมีคำสั่งกำหนดเอง:

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

โปรดทราบไวยากรณ์เก่าที่มีเครื่องหมายโคลอน

นอกจากนี้ยังมีวิธีใหม่ที่ดีกว่าในการใช้คลาสแบบมีเงื่อนไขเช่น:

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

ตอนนี้ Angular รองรับนิพจน์ที่คืนค่าวัตถุ แต่ละคุณสมบัติ (ชื่อ) ของวัตถุนี้ถือว่าเป็นชื่อคลาสและถูกนำไปใช้ขึ้นอยู่กับค่าของมัน

อย่างไรก็ตามวิธีการเหล่านี้ไม่สามารถใช้งานได้เท่ากัน นี่คือตัวอย่าง:

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

ดังนั้นเราจึงสามารถนำคลาส CSS ที่มีอยู่กลับมาใช้ใหม่ได้โดยการจับคู่คุณสมบัติของโมเดลกับชื่อคลาสและในขณะเดียวกันก็ป้องกันคลาส CSS ออกจากโค้ดคอนโทรลเลอร์


33
โอเพ่นนั่นอาจเป็นวิธีที่แย่ที่สุดในการแสดงโอเปอร์เรเตอร์ที่ฉันเคยเห็น คุณเคยคิด($index==selectedIndex) ? 'selected' : ''ไหม
Malvolio

17
@Malvolio AFAIR ผู้ประกอบการที่สามไม่ทำงานภายในนิพจน์เชิงมุมใน v0.9.x นี่เป็นสวิตช์มากหรือน้อย
orcun

36
ng-class (ณ วันที่ 1/19/2012) ขณะนี้สนับสนุนนิพจน์ที่ต้องประเมินเป็น 1) สตริงชื่อคลาสที่คั่นด้วยช่องว่างหรือ 2) และอาร์เรย์ของชื่อคลาสหรือ 3) แผนที่ / วัตถุของคลาส ชื่อไปยังค่าบูลีน ดังนั้นการใช้ 3): ng-class = "{เลือก: $ index == selectedIndex}"
Mark Rajcok

2
ขอบคุณ @ Mark, BTW ตอนนี้ฉันได้ตรวจสอบแล้วฉันสามารถพูดได้ว่าวิธีนี้ใช้งานได้ใน v1 มันยังมีประโยชน์ในบางกรณี โปรดทราบว่าชื่อคุณสมบัติของวัตถุ (กุญแจ) ไม่จำเป็นต้องเป็นจริงหรือเท็จมันอาจเป็นอะไรก็ได้ที่คุณอาจต้องการแมปกับชื่อคลาส
orcun

6
ฉันแค่ต้องการเพิ่มฉันมีปัญหาเพราะฉันใช้ไวยากรณ์เหมือน {classname: '$index === selectedIndex'} และมันไม่ทำงาน เมื่อฉันผลักทุกอย่างเข้าด้วยกันและใช้ == แทนที่จะเป็น === มันใช้ได้ {classname: '$index==selectedIndex'}
ลูคัส

437

ng-classรองรับการแสดงออกที่ต้องประเมินทั้ง

  1. สตริงของชื่อคลาสที่คั่นด้วยช่องว่างหรือ
  2. อาร์เรย์ของชื่อคลาสหรือ
  3. แผนที่ / วัตถุของชื่อชั้นเรียนเพื่อค่าบูลีน

ดังนั้นโดยใช้แบบฟอร์ม 3) เราสามารถเขียน

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

ดูเพิ่มเติมฉันจะใช้สไตล์ CSS กับ AngularJS ได้อย่างไร สำหรับคำตอบที่กว้างขึ้น


อัปเดต : Angular 1.1.5 ได้เพิ่มการสนับสนุนสำหรับผู้ประกอบการที่ประกอบไปด้วยสามดังนั้นหากการสร้างนั้นคุ้นเคยกับคุณมากกว่า:

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

2
+1 สำหรับผู้ประกอบการที่ประกอบไปด้วยสามคน (และฉันต้องการมันตอนนี้) แต่ 1.1. * เป็น 'รุ่นที่ไม่เสถียร' ซึ่ง API อาจมีการเปลี่ยนแปลงโดยไม่ต้องแจ้งให้ทราบล่วงหน้า - ณ เวลาที่พิมพ์ 1.0. * มีความเสถียรดังนั้นฉันจึงรู้สึกสบายใจที่จะทำเช่นนั้นสำหรับโครงการที่จะเปิดตัวในสัปดาห์หน้าเป็นเวลา 6 เดือน
Dave Everitt

1
ng-class="{'selected': $index==selectedIndex}"ใช้งานได้สำหรับฉัน
knuhol

160

วิธีที่ฉันชอบใช้การแสดงออกที่สาม

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

หมายเหตุ:ในกรณีที่คุณใช้ Angular รุ่นเก่ากว่าคุณควรใช้สิ่งนี้แทน

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

2
ng-class="property.name=='timestamp' ? 'property-timestamp' : 'property-'+{{$index}}"นี้ช่วยให้ฉันเขียนสำนวนนี้: ไม่สามารถหาวิธีอื่นได้
dduft

ฉันไม่พบสาเหตุที่แท้จริงของฉันบูลีน modalFlag ไม่อัพเดท - ng-class = "{'ปิด': modalFlag, 'เปิด':! modalFlag}" ฉันพยายามเพิ่มปิดหรือเปิดขึ้นอยู่กับตัวแปรที่ถูกกำหนด / บูลีน - ถ้าใครสามารถช่วยฉันจะขอบคุณมาก - ขอบคุณ
ลงจอด

นี่เป็นรุ่น 1.5 github.com/angular/angular.js/commit/…
Mubashir Koul

55

ฉันจะเพิ่มในสิ่งนี้เพราะคำตอบเหล่านี้บางคำดูเหมือนล้าสมัย นี่คือวิธีที่ฉันทำ:

<class="ng-class:isSelected">

โดยที่ 'isSelected' เป็นตัวแปรจาวาสคริปต์ที่กำหนดไว้ภายในตัวควบคุมเชิงมุมที่มีขอบเขต


ในการตอบคำถามของคุณโดยเฉพาะนี่คือวิธีที่คุณอาจสร้างรายการด้วย:

HTML

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


JS

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


ดู: http://jsfiddle.net/tTfWM/

ดู: http://docs.angularjs.org/api/ng.directive:ngClass


ข้อแตกต่างระหว่าง class = "ng-class: item.isSelected" และ ng-class = "item.isSelected"
zloctb

อยากรู้เรื่องการใช้ng-class:classNamevs เพิ่งใช้class="{{className}}"ไหม?
ร้อยเอ็ด

48

นี่เป็นวิธีที่ง่ายกว่ามาก:

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
ฉันขอแนะนำอย่างยิ่งให้ตัวควบคุมของคุณไม่ใช้ CSS นั่นคือเส้นทางที่คุณไม่ต้องการหัวลง
leviathan

1
ชื่อคลาสอยู่ในแม่แบบ
Casey

5
ในบางจุด jsfiddle อาจพลาดการชำระค่าใช้จ่ายของพวกเขาหรือเลือกที่จะย้ายไปยังโดเมนอื่นหรือผู้ที่รับผิดชอบถูกรถบัสฆ่า (ดู Bus Bus) ดังนั้นฉันขอให้คุณอธิบายสิ่งที่ซอทำในคำตอบของคุณ? นี่ก็เป็นที่ยอมรับในกองล้น
เซบาสเตียนมัค

27

ฉันพบปัญหาที่คล้ายกันเมื่อเร็ว ๆ นี้และตัดสินใจที่จะสร้างตัวกรองแบบมีเงื่อนไข:

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

มันต้องใช้อาร์กิวเมนต์เดี่ยวซึ่งเป็นทั้ง 2 องค์ประกอบของอาเรย์หรือสตริงซึ่งกลายเป็นอาเรย์ที่ต่อท้ายสตริงที่ว่างเปล่าเป็นองค์ประกอบที่สอง:

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

1
ฉันถึงฉันเพิ่งสร้างขึ้นเพื่อเป็นตัวอย่างตัวกรอง yesNo () ที่ส่งคืนคลาส 'ใช่' หรือ 'ไม่' ตามค่าบูลีน 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 สามารถจัดการกับแผนที่ / วัตถุของชื่อคลาสเป็นค่าบูลีนดังนั้นคุณสามารถเขียนสิ่งต่อไปนี้: ng-class = "{ใช่: some_boolean_expression, no: some_other_boolean_expression}" เช่น, ng-class = "{ใช่: อินพุต , no
:!

21

หากคุณต้องการไปไกลกว่าการประเมินเลขฐานสองและป้องกัน CSS ของคุณออกจากคอนโทรลเลอร์คุณสามารถใช้ตัวกรองแบบง่ายที่ประเมินการป้อนข้อมูลจากวัตถุแผนที่:

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

สิ่งนี้ช่วยให้คุณเขียนมาร์กอัปของคุณเช่นนี้:

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

สวัสดี @Joe ความคิดใด ๆ วิธีจัดการกับค่า Null? ถ้าฉันผ่าน null ในอินพุตมันจะไม่แมปคลาสของมัน ...
dalcam

1
@ user1191559 - คุณสามารถรายการ 'เริ่มต้น' ไปยังแผนที่จากนั้นส่งคืนค่านั้นหาก 'อินพุต' เป็นโมฆะ
Joe Steele

17

สิ่งที่ฉันทำเมื่อไม่นานมานี้คือการทำสิ่งนี้:

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

isShowingค่าเป็นค่าที่อยู่ในการควบคุมของฉันที่ได้รับการสลับด้วยการคลิกปุ่มและชิ้นส่วนระหว่างวงเล็บเดียวที่มีชั้นเรียนที่ฉันสร้างขึ้นในไฟล์ CSS ของฉัน

แก้ไข: ฉันต้องการเพิ่มที่ codeschool.com มีหลักสูตรฟรีที่สนับสนุนโดย google บน AngularJS ที่ครอบคลุมทุกสิ่งนี้แล้วบางส่วน ไม่จำเป็นต้องจ่ายอะไรเลยเพียงสมัครใช้งานบัญชีและเริ่มต้น! ขอให้โชคดีทุกคน!


คุณสามารถให้ซอหรือรหัสอื่น ๆ ที่นี่ได้ไหม คือisShowingอาร์เรย์ในการควบคุมแล้ว?
Kyle Pennell

ฉันเดาว่าเป็นบูลีน
Mirko

15

ประกอบ ternary ได้รับเพียงแค่เพิ่มการแยกวิเคราะห์เชิงมุมใน1.1.5

ดังนั้นวิธีที่ง่ายที่สุดที่จะทำคือตอนนี้:

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

นอกจากนี้: class="otherClass ng-class:($index==selectedIndex)? 'selected' : '';".
เตอร์

11

เราสามารถสร้างฟังก์ชั่นในการจัดการคลาสคืนโดยมีเงื่อนไข

ป้อนคำอธิบายรูปภาพที่นี่

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

และจากนั้น

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

คุณสามารถอ้างถึงหน้ารหัสเต็มได้ที่ตัวอย่างเช่น


9

ฉันใหม่กับ Angular แต่พบสิ่งนี้เพื่อแก้ปัญหาของฉัน:

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

สิ่งนี้จะใช้คลาสที่มีเงื่อนไขโดยยึดตาม var มันเริ่มต้นด้วยการดาวน์โหลดไอคอนเป็นค่าเริ่มต้นการใช้ ng-class ฉันจะตรวจสอบสถานะของshowDetailsถ้าtrue/falseและใช้ระดับไอคอนอัปโหลด มันใช้งานได้ดีมาก

หวังว่ามันจะช่วย


9

งานนี้เหมือนมีเสน่ห์;)

<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

นี่อาจจะเป็นการลดลงของการให้อภัย แต่นี่คือวิธีที่ฉันใช้ตัวดำเนินการแบบไตรภาคของ 1.1.5 เพื่อสลับคลาสโดยขึ้นอยู่กับว่าแถวในตารางเป็นอันดับแรกกลางหรือสุดท้าย - ยกเว้นถ้ามีเพียงหนึ่งแถวในตาราง:

<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

นี่คืองานของฉันหลายคนตัดสินโดยมีเงื่อนไข:

<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

นี่คือตัวเลือกอื่นที่ใช้งานได้ดีเมื่อไม่สามารถใช้ ng-class (ตัวอย่างเช่นเมื่อใส่สไตล์ SVG):

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

(ฉันคิดว่าคุณต้องเป็น Angular ที่ไม่เสถียรล่าสุดเพื่อใช้ ng-attr- ตอนนี้ฉันใช้ 1.1.4)


4

ดีฉันขอแนะนำให้คุณตรวจสอบสภาพในการควบคุมของคุณด้วยฟังก์ชั่นที่กลับมาจริงหรือเท็จ

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

และในตัวควบคุมของคุณตรวจสอบเงื่อนไข

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

4

เป็นบางส่วน

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

ตัวควบคุม

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

3

หากคุณใช้แองกูลาร์ v1.1.5 ก่อน (เช่นไม่มีผู้ประกอบการที่ประกอบไปด้วยสามภาค)และคุณยังต้องการวิธีที่เทียบเท่าในการตั้งค่าในทั้งสองเงื่อนไขคุณสามารถทำสิ่งนี้ได้:

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

3

หากคุณมีคลาสทั่วไปที่ใช้กับองค์ประกอบหลายอย่างคุณสามารถสร้างคำสั่งกำหนดเองที่จะเพิ่มคลาสนั้นเช่น ng-show / ng-hide

คำสั่งนี้จะเพิ่มคลาส 'ใช้งาน' ลงในปุ่มหากมีการคลิก

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

ข้อมูลเพิ่มเติม


3

เพียงแค่เพิ่มบางสิ่งบางอย่างที่ทำงานให้ฉันวันนี้หลังจากค้นหามาก ...

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

หวังว่านี่จะช่วยในการพัฒนาที่ประสบความสำเร็จของคุณ

=)

ไวยากรณ์ของนิพจน์ที่ไม่มีเอกสาร: ลิงค์เว็บไซต์ที่ยอดเยี่ยม ... =)


ตรวจสอบคำตอบที่ยอมรับได้ มันกำลังทำสิ่งเดียวกันและให้ตัวอย่างเพิ่มเติม
respectTheCode

3

ตรวจสอบนี้

if|elseคำสั่งAngularJS ที่น่าอับอาย!!!
เมื่อฉันเริ่มใช้ Angularjs ฉันรู้สึกประหลาดใจเล็กน้อยที่ฉันไม่พบคำสั่ง if / else

ดังนั้นฉันจึงกำลังทำงานในโครงการและฉันสังเกตเห็นว่าเมื่อใช้คำสั่ง if / else เงื่อนไขจะปรากฏขึ้นขณะกำลังโหลด คุณสามารถใช้ ng-cloak เพื่อแก้ไขปัญหานี้

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

ขอบคุณอะมาโดะ


0

คุณสามารถใช้นี้แพคเกจ NPM มันจัดการทุกอย่างและมีตัวเลือกสำหรับการเรียนแบบคงที่และมีเงื่อนไขขึ้นอยู่กับตัวแปรหรือฟังก์ชั่น

// 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})} />
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.