Bagaimana cara saya menerapkan gaya CSS di AngularJS?

309

Q1. Misalkan saya ingin mengubah tampilan setiap "item" yang ditandai pengguna untuk dihapus sebelum tombol "hapus" utama ditekan. (Umpan balik visual langsung ini harus menghilangkan kebutuhan untuk kotak dialog "apakah Anda yakin?" Pepatah.) Pengguna akan memeriksa kotak centang untuk menunjukkan item mana yang harus dihapus. Jika kotak centang tidak dicentang, item itu harus kembali ke tampilan normal.

Apa cara terbaik untuk menerapkan atau menghapus gaya CSS?

Q2. Misalkan saya ingin mengizinkan setiap pengguna untuk mempersonalisasi bagaimana situs saya disajikan. Misalnya, pilih dari kumpulan ukuran font yang tetap, memungkinkan warna latar depan dan latar belakang yang dapat ditentukan pengguna, dll

Apa cara terbaik untuk menerapkan penataan CSS yang dipilih / input pengguna?

Mark Rajcok
sumber
artikel bermanfaat tech-blog.maddyzone.com/javascript/…
Rituraj ratan

Jawaban:

485

Angular menyediakan sejumlah arahan bawaan untuk memanipulasi penataan CSS secara kondisional / dinamis:

  • ng-class - digunakan ketika set gaya CSS statis / dikenal sebelumnya
  • ng-style - gunakan ketika Anda tidak dapat mendefinisikan kelas CSS karena nilai style dapat berubah secara dinamis. Pikirkan kontrol nilai nilai gaya yang dapat diprogram.
  • ng-show dan ng-hide - gunakan jika Anda hanya perlu menampilkan atau menyembunyikan sesuatu (memodifikasi CSS)
  • ng-if - baru dalam versi 1.1.5, gunakan alih-alih verbose ng-switch yang lebih banyak jika Anda hanya perlu memeriksa satu kondisi (memodifikasi DOM)
  • ng-switch - gunakan alih-alih menggunakan beberapa pertunjukan ng yang saling eksklusif (modifikasi DOM)
  • ng-disable dan ng-readonly - gunakan untuk membatasi perilaku elemen form
  • ng-animate - baru dalam versi 1.1.4, gunakan untuk menambahkan transisi / animasi CSS3

"Cara sudut" normal melibatkan pengikatan properti model / lingkup ke elemen UI yang akan menerima input / manipulasi pengguna (yaitu, menggunakan model-ng), dan kemudian mengaitkan properti model itu ke salah satu arahan built-in yang disebutkan di atas.

Ketika pengguna mengubah UI, Angular akan secara otomatis memperbarui elemen terkait pada halaman.


Q1 terdengar seperti kasus yang bagus untuk ng-class - gaya CSS dapat ditangkap di kelas.

ng-class menerima "ekspresi" yang harus mengevaluasi ke salah satu dari yang berikut:

  1. serangkaian nama kelas yang dibatasi ruang
  2. array nama kelas
  3. peta / objek nama kelas ke nilai boolean

Dengan asumsi item Anda ditampilkan menggunakan ng-repeat pada beberapa model array, dan ketika kotak centang untuk item dicentang Anda ingin menerapkan pending-deletekelas:

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

Di atas, kami menggunakan tipe ekspresi ng-class # 3 - peta / objek nama kelas ke nilai boolean.


Q2 terdengar seperti kasus yang bagus untuk gaya ng - gaya CSS dinamis, jadi kami tidak dapat menentukan kelas untuk ini.

ng-style menerima "ekspresi" yang harus dievaluasi untuk:

  1. peta / objek nama gaya CSS ke nilai CSS

Untuk contoh yang dibuat-buat, misalkan pengguna dapat mengetikkan nama warna ke kotak teks untuk warna latar belakang (pemilih warna jQuery akan jauh lebih baik):

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


Biola untuk kedua hal di atas.

Biola juga berisi contoh ng-show dan ng-hide . Jika kotak centang dicentang, selain warna latar belakang berubah menjadi merah muda, beberapa teks ditampilkan. Jika 'merah' dimasukkan dalam kotak teks, sebuah div menjadi tersembunyi.

Mark Rajcok
sumber
Jawaban ini luar biasa! Apakah Anda bersedia menunjukkan kepada saya melalui jsfiddle apa perbedaannya jika acara klik mengubah / menambahkan kelas pada area yang bukan elemen yang diklik? Ucapkan div di tempat lain di halaman.
tehaaron
itu adalah artikel yang berguna tech-blog.maddyzone.com/javascript/…
Rituraj ratan
Jawaban yang bagus. Btw, apakah Anda pernah mencoba menerapkan filter sudut ke gaya ng?
Evi Song
Saya menyarankan menambahkan opsi tambahan yang terkait dengan Q2 yang baru saja saya tambahkan dalam jawaban terakhir saya untuk pertanyaan ini.
Gavin Palmer
105

Saya telah menemukan masalah ketika menerapkan kelas di dalam elemen tabel ketika saya memiliki satu kelas yang sudah diterapkan ke seluruh tabel (misalnya, warna yang diterapkan pada baris aneh <myClass tbody tr:nth-child(even) td>). Tampaknya ketika Anda memeriksa elemen dengan Alat Pengembang , element.stylegaya tidak ditugaskan. Jadi alih-alih menggunakan ng-class, saya sudah mencoba menggunakan ng-style, dan dalam hal ini, atribut CSS baru muncul di dalamnya element.style. Kode ini sangat bagus untuk saya:

<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 adalah apa yang saya evaluasi, dan dalam setiap kasus saya menerapkan gaya untuk masing <td>- masing tergantung pada nilai myvar , yang menimpa gaya saat ini yang diterapkan oleh kelas CSS untuk seluruh tabel.

MEMPERBARUI

Jika Anda ingin menerapkan kelas ke tabel misalnya, saat mengunjungi halaman atau dalam kasus lain, Anda dapat menggunakan struktur ini:

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

Pada dasarnya, apa yang kita butuhkan untuk mengaktifkan kelas-ng adalah kelas untuk diterapkan dan pernyataan benar atau salah. Benar berlaku kelas dan palsu tidak. Jadi di sini kita memiliki dua pemeriksaan rute halaman dan OR di antara mereka, jadi jika kita berada di /route_a OR kita berada di route_b, kelas aktif akan diterapkan.

Ini berfungsi hanya memiliki fungsi logika di sebelah kanan yang mengembalikan benar atau salah.

Jadi dalam contoh pertama, ng-style dikondisikan oleh tiga pernyataan. Jika semuanya salah, tidak ada gaya yang diterapkan, tetapi mengikuti logika kita, setidaknya satu akan diterapkan, jadi, ekspresi logika akan memeriksa perbandingan variabel mana yang benar dan karena array yang tidak kosong selalu benar, yang akan meninggalkan array sebagai return dan dengan hanya satu true, mengingat kita menggunakan OR untuk seluruh respons, gaya yang tersisa akan diterapkan.

Omong-omong, saya lupa memberi Anda fungsi isActive ():

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

PEMBARUAN BARU

Di sini Anda memiliki sesuatu yang saya temukan sangat berguna. Ketika Anda perlu menerapkan kelas tergantung pada nilai variabel, misalnya, ikon tergantung pada konten div, Anda dapat menggunakan kode berikut (sangat berguna dalam ng-repeat):

<i class="fa" ng-class="{ 'fa-github'   : type === 0,
                          'fa-linkedin' : type === 1,
                          'fa-skype'    : type === 2,
                          'fa-google'   : type === 3 }"></i>

Ikon dari Font Awesome

Timbergus
sumber
apa arti sintaksis yang aneh, && seharusnya DAN, seperti dalam bahasa yang diilhami c lainnya
Pizzaiola Gorgonzola
3
@PizzaiolaGorgonzola && artinya AND dan || artinya ATAU. Ini peretasan cerdas menggunakan logika hubung singkat hampir sebagai pernyataan case / switch ...
Stein G. Strindhaug
Terima kasih mit. Saya tidak menyadari detail itu.
Timbergus
Bagian pembaruan baru berfungsi seperti pesona! +1 untuk itu!
Matias
menggunakan contoh ng-class seperti yang disebutkan dalam Pembaruan Baru, bekerja cukup baik untuk saya. Cukup ramping
Acewin
34

Ini berfungsi dengan baik ketika ng-class tidak dapat digunakan (misalnya ketika menata SVG):

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

(Saya pikir Anda harus menggunakan Angular terbaru yang tidak stabil untuk menggunakan ng-attr-, saya saat ini di 1.1.4)

Saya telah menerbitkan artikel tentang bekerja dengan AngularJS + SVG. Ini berbicara tentang masalah ini dan banyak lainnya. http://www.codeproject.com/Articles/709340/Implementing-a-Flowchart-with-SVG-and-AngularJS

Ashley Davis
sumber
Saya tidak melihat penyebutan ng-attr di dokumen 1.1.4 - apakah Anda memiliki tautan?
Mark Rajcok
Maaf tidak punya tautan. Saya mengetahuinya dengan mengikuti forum Angular, meskipun saya tidak dapat mengingat halaman yang sebenarnya maaf.
Ashley Davis
1
Dokumen terbaru (v1.2) menjelaskan ng-attr-pada halaman arahan , bagian ngAttr atribut binding .
Mark Rajcok
Dengan 1.2, ini menjadi jawaban yang bagus. ng-classtidak membiarkan Anda melakukan logika, tetapi ng-attr-classmelakukannya. Mereka berdua memiliki kegunaan mereka, tetapi saya bisa bertaruh banyak pengembang akan mencari ng-attr-class.
Hylianpuffball
Saya mendapatkan ini berfungsi dengan baik ketika solusi lain yang disediakan di sini gagal. Terima kasih.
dps
13
span class="circle circle-{{selectcss(document.Extension)}}">

dan kode

$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);
}
Nenad Jesic
sumber
Selalu menghindari kata iF
LastTribunal
Saya ingin mendorong untuk menghindari langsung menggunakan atribut-kelas. Ini akan menimpa perubahan yang dibuat oleh plugin lain pada elemen ini.
SimonSimCity
10

Solusi ini membantu saya

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

Anda dapat menggunakan ekspresi ternary. Ada dua cara untuk melakukan ini:

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

atau...

<div ng-style="{'color': (myVariable > 100) ? 'red' : 'blue' }"></div>
michal-michalak
sumber
1
Mungkin Anda akan menemukannya lebih baik: <div ng-style = "{'color': (myVariable> 100)? 'Red': 'blue'}"> </div>
Dudi
Dudi, jika tidak lebih baik, sama bermanfaatnya, jadi saya menambahkannya ke jawaban "mayary expression" @ maykel. Terima kasih untuk kalian berdua!
jbobbins
7

Opsi lain ketika Anda membutuhkan gaya css sederhana dari satu atau dua properti:

Melihat:

<tr ng-repeat="element in collection">
    [...amazing code...] 
    <td ng-style="{'background-color': getTrColor(element.myvar)}">
        {{ element.myvar }}
    </td>
    [...more amazing code...]
</tr>

Pengendali:

$scope.getTrColor = function (colorIndex) {
    switch(colorIndex){
        case 0: return 'red';
        case 1: return 'green';
        default: return 'yellow';
    }
};
Dudi
sumber
6

Lihat contoh berikut

<!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>
Ranga Reddy
sumber
2

Pada AngularJS v1.2.0rc, ng-classdan bahkanng-attr-class gagal dengan elemen SVG (Mereka memang bekerja sebelumnya, bahkan dengan pengikatan normal di dalam atribut class)

Secara khusus, tidak ada yang berfungsi sekarang:

ng-class="current==this_element?'active':' ' "
ng-attr-class="{{current==this_element?'active':' '}}"
class="class1 class2 .... {{current==this_element?'active':''}}"

Sebagai solusinya, saya harus menggunakan

ng-attr-otherAttr="{{current==this_element?'active':''}}"

dan kemudian gaya menggunakan

[otherAttr='active'] {
   ... styles ...
}
kumarharsh
sumber
1

Satu lagi (di masa depan) cara menerapkan gaya secara kondisional adalah dengan menciptakan gaya scoped

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

</style>

Tetapi saat ini hanya FireFox yang mendukung gaya cakupan.

Pavel Voronin
sumber
1

Ada satu opsi lagi yang baru-baru ini saya temukan bahwa beberapa orang mungkin menemukan berguna karena memungkinkan Anda untuk mengubah aturan CSS dalam elemen gaya - sehingga menghindari kebutuhan untuk penggunaan berulang dari arahan sudut seperti ng-style, ng-class, ng-show, ng-hide, ng-animate, dan lainnya.

Opsi ini memanfaatkan layanan dengan variabel layanan yang ditetapkan oleh pengontrol dan ditonton oleh atribut-directive yang saya sebut "custom-style". Strategi ini dapat digunakan dalam banyak cara yang berbeda, dan saya berusaha memberikan panduan umum dengan biola ini .

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);
        }
    };
});
Gavin Palmer
sumber
1

baik saya akan menyarankan Anda untuk memeriksa kondisi di controller Anda dengan fungsi yang mengembalikan benar atau salah .

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

dan di controller Anda periksa kondisinya

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

Satu hal yang perlu diperhatikan adalah - jika gaya CSS memiliki tanda hubung - Anda harus menghapusnya. Jadi jika Anda ingin mengatur background-color, cara yang benar adalah:

ng-style="{backgroundColor:myColor}" 
Neil Munro
sumber
5
Tidak, kamu tidak harus. ng-style = "{'background-color': myColor}" berfungsi dengan sangat baik.
gerasalus
0

Inilah cara saya menerapkan gaya teks abu-abu pada tombol yang dinonaktifkan

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

Berikut ini contoh yang berfungsi:
https://stackblitz.com/edit/example-conditional-disable-button?file=src%2Fapp%2Fapp.component.html

BraveNewMath
sumber