ฉันจะใช้สไตล์ CSS อย่างมีเงื่อนไขใน AngularJS ได้อย่างไร


309

ไตรมาสที่ 1 สมมติว่าฉันต้องการเปลี่ยนลักษณะของ "รายการ" แต่ละรายการที่ผู้ใช้ทำเครื่องหมายเพื่อลบก่อนกดปุ่ม "ลบ" หลัก (คำติชมภาพทันทีนี้ควรกำจัดความต้องการสุภาษิต "คุณแน่ใจหรือไม่" กล่องโต้ตอบ) ผู้ใช้จะทำเครื่องหมายในช่องทำเครื่องหมายเพื่อระบุรายการที่ควรจะลบ หากไม่ได้เลือกช่องทำเครื่องหมายรายการนั้นควรเปลี่ยนกลับเป็นรูปลักษณ์ปกติ

เป็นวิธีที่ดีที่สุดในการใช้หรือลบสไตล์ CSS คืออะไร?

ไตรมาสที่ 2 สมมติว่าฉันต้องการอนุญาตให้ผู้ใช้แต่ละคนปรับเปลี่ยนวิธีการนำเสนอไซต์ของฉันในแบบของฉัน เช่นเลือกจากชุดขนาดตัวอักษรคงที่อนุญาตให้ผู้ใช้กำหนดสีพื้นหน้าและสีพื้นหลัง ฯลฯ

เป็นวิธีที่ดีที่สุดในการใช้สไตล์ CSS ที่ผู้ใช้เลือก / อินพุตคืออะไร?


บทความที่มีประโยชน์tech-blog.maddyzone.com/javascript/…
Rituraj ratan

คำตอบ:


485

Angular มีคำสั่งในตัวจำนวนมากสำหรับจัดการ CSS สไตล์ตามเงื่อนไข / แบบไดนามิก:

  • ng-class - ใช้เมื่อชุดของสไตล์ CSS เป็นแบบสแตติก / รู้จักล่วงหน้า
  • ng-style - ใช้เมื่อคุณไม่สามารถกำหนดคลาส CSS ได้เนื่องจากค่าสไตล์อาจเปลี่ยนแปลงแบบไดนามิก คิดว่าการควบคุมค่าสไตล์ของโปรแกรมได้
  • ng-showและ ng-hide - ใช้ถ้าคุณต้องการแสดงหรือซ่อนบางสิ่ง (แก้ไข CSS)
  • ng-if - ใหม่ในเวอร์ชัน 1.1.5, ใช้แทน verbose เพิ่มเติม ng-switch หากคุณต้องการตรวจสอบเงื่อนไขเดียว (แก้ไข DOM)
  • ng-switch - ใช้แทนการใช้ ng-shows พิเศษร่วมกันหลายรายการ (แก้ไข DOM)
  • ng- ปิดการใช้งานและ ng-readonly - ใช้เพื่อ จำกัด พฤติกรรมองค์ประกอบของแบบฟอร์ม
  • NG-เคลื่อนไหว - ใหม่ในเวอร์ชัน 1.1.4 ใช้เพื่อเพิ่มการเปลี่ยน / ภาพเคลื่อนไหว CSS3

ปกติ "วิธีเชิงมุม" เกี่ยวข้องกับการผูกคุณสมบัติโมเดล / ขอบเขตให้กับองค์ประกอบ UI ที่จะยอมรับอินพุต / การจัดการของผู้ใช้ (เช่นใช้ ng-model) แล้วเชื่อมโยงคุณสมบัติของโมเดลนั้นกับหนึ่งในคำสั่งในตัวที่กล่าวถึงข้างต้น

เมื่อผู้ใช้เปลี่ยน UI Angular จะอัปเดตองค์ประกอบที่เกี่ยวข้องในหน้าโดยอัตโนมัติ


Q1 ดูเหมือนเป็นกรณีที่ดีสำหรับ ng-class - สไตล์ CSS สามารถจับภาพได้ในชั้นเรียน

ng-classยอมรับ "expression" ที่ต้องประเมินเป็นอย่างใดอย่างหนึ่งต่อไปนี้:

  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 expression type # 3 - แผนที่ / วัตถุของชื่อคลาสเป็นค่าบูลีน


Q2 ฟังดูดีสำหรับ ng-style การใส่สไตล์ CSS เป็นแบบไดนามิกดังนั้นเราจึงไม่สามารถกำหนดคลาสสำหรับสิ่งนี้ได้

ng-styleยอมรับ "expression" ที่ต้องประเมินเพื่อ:

  1. แม็พ / อ็อบเจ็กต์ของชื่อสไตล์ CSS กับค่า CSS

สำหรับตัวอย่างที่วางแผนไว้สมมติว่าผู้ใช้สามารถพิมพ์ชื่อสีลงใน texbox สำหรับสีพื้นหลัง (ตัวเลือกสี jQuery จะดีกว่า):

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


ซอสำหรับทั้งสองข้างต้น

ซอนอกจากนี้ยังมีตัวอย่างของNG-แสดงและng ซ่อน หากทำเครื่องหมายที่ช่องทำเครื่องหมายนอกเหนือจากการเปลี่ยนเป็นสีพื้นหลังสีชมพูข้อความบางส่วนจะปรากฏขึ้น หากมีการป้อน 'สีแดง' ในกล่องข้อความ div จะถูกซ่อน


คำตอบนี้ยอดเยี่ยมมาก! คุณยินดีที่จะแสดงให้ฉันเห็นผ่าน jsfiddle ว่าเหตุการณ์คลิกจะเปลี่ยนแปลงหรือเพิ่มคลาสในพื้นที่ที่ไม่ใช่องค์ประกอบคลิกหรือไม่ พูด div ที่อื่นในหน้า
tehaaron

มันเป็นบทความที่มีประโยชน์tech-blog.maddyzone.com/javascript/…
Rituraj ratan

เยี่ยมมาก คุณเคยลองใช้ฟิลเตอร์เชิงมุมกับสไตล์ ng หรือไม่?
Evi Song

ฉันขอแนะนำให้เพิ่มตัวเลือกเพิ่มเติมที่เกี่ยวข้องกับไตรมาส 2 ที่ฉันเพิ่งเพิ่มในคำตอบล่าสุดของคำถามนี้
Gavin Palmer

105

ฉันพบปัญหาเมื่อใช้คลาสภายในองค์ประกอบของตารางเมื่อฉันมีหนึ่งคลาสที่ใช้กับตารางทั้งหมดแล้ว (ตัวอย่างเช่นสีที่ใช้กับแถวคี่<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คือสิ่งที่ฉันกำลังประเมินและในแต่ละกรณีฉันใช้สไตล์กับแต่ละค่า<td>ขึ้นอยู่กับค่าmyvarที่จะเขียนทับสไตล์ปัจจุบันที่ใช้โดยคลาส CSS สำหรับทั้งตาราง

UPDATE

หากคุณต้องการใช้คลาสกับตารางเช่นเมื่อไปที่หน้าหรือในกรณีอื่นคุณสามารถใช้โครงสร้างนี้:

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

โดยพื้นฐานแล้วสิ่งที่เราต้องเปิดใช้งานng-classคือคลาสที่จะใช้และคำสั่งจริงหรือเท็จ Trueใช้คลาสและfalseไม่ได้ ดังนั้นที่นี่เรามีสองการตรวจสอบเส้นทางของหน้าและORระหว่างพวกเขาดังนั้นหากเราอยู่ใน/route_a หรือเราอยู่ในroute_bการใช้งานระดับจะนำไปใช้

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

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

อย่างไรก็ตามฉันลืมให้ฟังก์ชัน 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>

ไอคอนจากFont Awesome


ซินแท็คซ์เป็นสิ่งที่แปลก & & ควรจะหมายความว่าและเช่นในภาษาอื่น ๆ แรงบันดาลใจค
Pizzaiola Gorgonzola

3
@PizzaiolaGorgonzola && หมายถึง AND และ || หมายความว่าหรือ มันสับฉลาดใช้ตรรกะลัดวงจรเกือบจะเป็นคำสั่งกรณี / สวิทช์ ...
สไตน์กรัม Strindhaug

ขอขอบคุณ ฉันไม่ได้ตระหนักถึงรายละเอียดนั้น
Timbergus

ส่วนอัปเดตใหม่ใช้งานได้อย่างมีเสน่ห์! +1 สำหรับมัน!
Matias

ใช้ตัวอย่างของ ng-class ดังกล่าวใน New Update ทำงานได้ดีสำหรับฉัน สวยเพรียวบาง
Acewin

34

ใช้งานได้ดีเมื่อไม่สามารถใช้ 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


ฉันไม่เห็นพูดถึง ng-attr ในเอกสาร 1.1.4 - คุณมีลิงค์หรือไม่?
Mark Rajcok

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

1
เอกสารล่าสุด (v1.2) อธิบายng-attr-ในหน้าคำสั่งส่วนngAttr ผูกแอตทริบิวต์
Mark Rajcok

ด้วย 1.2 นี่เป็นคำตอบที่ยอดเยี่ยม ng-classไม่อนุญาตให้คุณทำตรรกะ แต่ng-attr-classทำ พวกเขาทั้งสองมีการใช้ของพวกเขา ng-attr-classแต่ฉันสามารถวางเดิมพันมากนักพัฒนาจะมองหา
Hylianpuffball

ฉันได้สิ่งนี้ทำงานได้ดีเมื่อโซลูชันอื่น ๆ ที่ให้ไว้ที่นี่ล้มเหลว ขอบคุณ.
dps

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

หลีกเลี่ยงคำ iF ทุกครั้ง
LastTribunal

ฉันต้องการสนับสนุนให้หลีกเลี่ยงการใช้ class-attribute โดยตรง สิ่งนี้จะเขียนทับการเปลี่ยนแปลงที่ทำโดยปลั๊กอินอื่น ๆ ในองค์ประกอบนี้
SimonSimCity

10

วิธีการแก้ปัญหานี้ทำเพื่อฉัน

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

8

คุณสามารถใช้นิพจน์ประกอบไปด้วย มีสองวิธีในการทำสิ่งนี้:

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

หรือ...

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

1
บางทีคุณอาจจะพบว่าดีกว่า: <div ng-style = "{'color': (myVariable> 100)? 'red': 'blue'}"> </div>
Dudi

Dudi ถ้าไม่ดีขึ้นก็มีประโยชน์เหมือนกันดังนั้นฉันจึงเพิ่มคำตอบ "ternary expression" ของ @ maykel ขอบคุณทั้งคุณ!
jbobbins

7

ตัวเลือกอื่นเมื่อคุณต้องการสไตล์ 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';
    }
};

6

ดูตัวอย่างต่อไปนี้

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

2

ในฐานะของ 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 ...
}

1

อีกวิธีหนึ่งในการใช้สไตล์แบบมีเงื่อนไขคือโดยการสร้างสไตล์แบบมีเงื่อนไข

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

</style>

แต่ทุกวันนี้มีเพียง FireFox เท่านั้นที่รองรับสไตล์ที่กำหนดขอบเขต


1

มีอีกตัวเลือกหนึ่งที่ฉันเพิ่งค้นพบว่าบางคนอาจพบว่ามีประโยชน์เพราะมันช่วยให้คุณเปลี่ยนกฎ CSS ภายในองค์ประกอบสไตล์ - ดังนั้นหลีกเลี่ยงความจำเป็นในการใช้คำสั่งเชิงมุมซ้ำ ๆ เช่น 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);
        }
    };
});

1

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

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

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

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

0

สิ่งหนึ่งที่ควรระวังคือ - ถ้าสไตล์ CSS มีขีดกลาง - คุณต้องลบ ดังนั้นหากคุณต้องการตั้งค่าbackground-colorวิธีที่ถูกต้องคือ:

ng-style="{backgroundColor:myColor}" 

5
ไม่คุณไม่ต้องทำ ng-style = "{'background-color': myColor}" ทำงานได้อย่างสมบูรณ์แบบ
gerasalus

0

นี่คือวิธีที่ฉันใช้สไตล์ข้อความสีเทาแบบมีเงื่อนไขบนปุ่มปิดใช้งาน

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

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