AngularJS'de CSS stillerini koşullu olarak nasıl uygularım?


309

S1. Ana "sil" düğmesine basılmadan önce bir kullanıcının silmek üzere işaretlediği her "öğenin" görünümünü değiştirmek istediğinizi varsayalım. (Bu anında görsel geri bildirim, "emin misiniz?" Atasözüne olan ihtiyacı ortadan kaldırmalıdır.) Kullanıcı, hangi öğelerin silineceğini belirtmek için onay kutularını işaretleyecektir. Bir onay kutusunun işareti kaldırılırsa, bu öğe normal görünümüne geri dönmelidir.

CSS stilini uygulamanın veya kaldırmanın en iyi yolu nedir?

S2. Her kullanıcının sitemin sunulma şeklini kişiselleştirmesine izin vermek istediğimi varsayalım. Örneğin, sabit yazı tipi boyutu kümesinden seçim yapın, kullanıcı tanımlı ön plan ve arka plan renklerine izin verin vb.

Kullanıcının seçtiği / girdiği CSS stilini uygulamanın en iyi yolu nedir?


Yanıtlar:


485

Açısal, CSS stilini koşullu / dinamik olarak değiştirmek için bir dizi yerleşik yönerge sağlar:

  • ng-sınıfı - CSS stilleri kümesi statik / önceden biliniyorsa kullanın
  • ng stili - stil değerleri dinamik olarak değişebileceğinden bir CSS sınıfı tanımlayamadığınızda kullanın. Stil değerlerinin programlanabilir kontrolünü düşünün.
  • ng-show ve ng-hide - yalnızca bir şey göstermeniz veya gizlemeniz gerekiyorsa kullanın (CSS'yi değiştirir)
  • ng-if - sürüm 1.1.5'te yeni, yalnızca tek bir koşulu kontrol etmeniz gerekiyorsa daha ayrıntılı ng-switch yerine kullanın (DOM'u değiştirir)
  • ng-switch - birbirini dışlayan birkaç ng-show kullanmak yerine kullanın (DOM'u değiştirir)
  • ng devre dışı ve salt okunur - form öğesi davranışını kısıtlamak için kullanın
  • ng-animate - sürüm 1.1.4'te yeni, CSS3 geçişleri / animasyonları eklemek için kullanın

Normal "Açısal yol", kullanıcı girişini / manipülasyonunu kabul edecek (yani ng-modelini kullanacak) bir UI öğesine bir model / kapsam özelliği bağlamayı ve daha sonra bu model özelliğini yukarıda belirtilen yerleşik yönergelerden biriyle ilişkilendirmeyi içerir.

Kullanıcı kullanıcı arayüzünü değiştirdiğinde Angular, sayfadaki ilişkili öğeleri otomatik olarak güncelleyecektir.


Q1, ng sınıfı için iyi bir durum gibi görünüyor - CSS stili bir sınıfta yakalanabilir.

ng-class aşağıdakilerden birini değerlendirmesi gereken bir "ifadeyi" kabul eder:

  1. boşlukla sınırlandırılmış sınıf adları dizesi
  2. sınıf isimleri dizisi
  3. sınıf adlarının boole değerleriyle eşlemesi / nesnesi

Öğelerinizin bazı dizi modellerinde ng-repeat kullanılarak görüntülendiğini ve bir öğenin onay kutusunun işaretlendiğinde pending-deletesınıfı uygulamak istediğinizi varsayarsak :

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

Yukarıda, boolean değerlerine sınıf adlarının bir haritası / nesnesi olan ng sınıfı ifade türü # 3'ü kullandık.


Q2, ng tarzı için iyi bir durum gibi görünüyor - CSS stili dinamiktir, bu nedenle bunun için bir sınıf tanımlayamayız.

ng-tarzı , aşağıdakiler için değerlendirilmesi gereken bir "ifadeyi" kabul eder:

  1. CSS stil adlarının CSS değerleriyle eşlenmesi / nesnesi

Çağdaş bir örnek için, kullanıcının arka plan rengi için bir metin kutusuna bir renk adı yazabileceğini varsayalım (bir jQuery renk seçici çok daha hoş olurdu):

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


Yukarıdakilerin her ikisi için de keman .

Keman ayrıca bir ng-show ve ng-hide örneği içerir . Bir onay kutusu işaretlenirse, arka plan rengi pembeye dönüşmeye ek olarak, bazı metinler gösterilir. Metin kutusuna 'kırmızı' girilirse, bir div gizlenir.


Bu cevap müthiş! Tıklama olayı, tıklanan öğe olmayan bir alana bir sınıf ekliyorsa / ekliyorsa, bana jsfiddle aracılığıyla ne olacağını göstermeye istekli misiniz? Sayfanın başka bir yerinde bir div deyin.
tehaaron


Harika anwser. Btw, ng-stiline açısal filtre uygulamayı denediniz mi?
Evi Song

Bu soruya son yanıtımda yeni eklediğim 2. Çeyrek ile ilgili ek bir seçenek eklemenizi öneririm.
Gavin Palmer

105

Tüm tabloya zaten uygulanmış bir sınıf (örneğin, tek satırlara uygulanan bir renk) olduğunda tablo öğeleri içinde sınıfları uygularken sorunlar buldum <myClass tbody tr:nth-child(even) td>. Birlikte öğeyi denetle zaman görünüyor Geliştirici Araçları , element.styleatanmış bir tarzı vardır. Yani kullanmak yerine kullanmayı ng-classdenedim ng-styleve bu durumda yeni CSS özelliği içeride görünüyor element.style. Bu kod benim için harika çalışıyor:

<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 , değerlendirdiğim şeydir ve her durumda , tüm tablo için CSS sınıfı tarafından uygulanan geçerli stilin üzerine yazan, myvar değerine <td>bağlı olarak her birine bir stil uygularım .

GÜNCELLEME

Örneğin, bir sayfayı ziyaret ederken veya diğer durumlarda tabloya bir sınıf uygulamak istiyorsanız, bu yapıyı kullanabilirsiniz:

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

Temel olarak, bir ng sınıfını etkinleştirmek için ihtiyacımız olan , uygulanacak sınıf ve doğru veya yanlış bir ifadedir. True sınıfı uygular ve false uygulamaz. Yani burada biz sayfanın güzergahı ve bir iki çekler var OR içinde bulunduğumuz eğer öyleyse, aralarında /route_a VEYA içinde bulunduğumuz route_b, aktif sınıf uygulanacaktır.

Bu, sağda doğru veya yanlış döndüren bir mantık işlevine sahip olarak çalışır.

İlk örnekte, ng-tarzı üç ifadeyle koşullandırılmıştır. Hepsi yanlışsa, stil uygulanmaz, ancak mantığımıza göre en az bir tane uygulanır, bu nedenle mantık ifadesi hangi değişken karşılaştırmasının doğru olduğunu ve boş olmayan bir dizi her zaman doğru olduğundan, bir dizi dönüş olarak bırakıldı ve tüm yanıt için OR kullandığımızı düşünürsek , kalan stil uygulanacaktır.

Bu arada, size isActive () işlevini vermeyi unuttum:

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

YENİ GÜNCELLEME

Burada gerçekten yararlı bulduğum bir şey var. Bir değişkenin değerine bağlı olarak bir sınıf uygulamanız gerektiğinde, örneğin, içeriğine bağlı olarak bir simge div, aşağıdaki kodu kullanabilirsiniz (çok kullanışlı 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'den simgeler


Diğer garip bir sözdiziminde olduğu gibi VE tuhaf bir sözdizimi & AND anlamına gelmelidir
Pizzaiola Gorgonzola

3
@PizzaiolaGorgonzola &&, AND ve || anlamına gelir || "OR" anlamına gelir. Kısa devre mantığını neredeyse bir vaka / anahtar ifadesi olarak kullanan akıllı bir hack ...
Stein G. Strindhaug

Teşekkürler mit. Bu ayrıntıyı fark etmedim.
Timbergus

Yeni güncelleme bölümü bir cazibe gibi çalıştı! Bunun için +1!
Matias

New Update'te bahsedildiği gibi ng-class örneğini kullandım, benim için oldukça iyi çalıştı. Oldukça şık
Acewin

34

Ng sınıfı kullanılamadığında bu işe yarar (örneğin SVG'yi şekillendirirken):

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

(Ng-attr- kullanmak için en son dengesiz açısal olmanız gerektiğini düşünüyorum, şu anda 1.1.4'deyim)

AngularJS + SVG ile çalışma hakkında bir makale yayınladım. Bu konu ve diğer pek çok konu hakkında konuşuyor. http://www.codeproject.com/Articles/709340/Implementing-a-Flowchart-with-SVG-and-AngularJS


1.1.4 dokümanda ng-attr'dan hiç bahsetmiyorum - bağlantınız var mı?
Mark Rajcok

Üzgünüm, bir bağlantım yok. Kesin sayfayı tam olarak hatırlayamama rağmen, Açısal forumları takip ederek bunu öğrendim.
Ashley Davis

1
En yeni dokümanlara (v1.2) tarif ng-attr-üzerine direktifler sayfasında , bölüm ngAttr nitelik bağlamaları .
Mark Rajcok

1.2 ile bu harika bir cevap olur. ng-classmantık yapmanıza izin vermez, ama ng-attr-class. Her ikisinin de kullanımları var, ancak birçok geliştiricinin arayacağına bahse girebilirim ng-attr-class.
Hylianpuffball

Burada sağlanan diğer çözümler başarısız olduğunda bunu işe yaradı. Teşekkür ederim.
dps

13
span class="circle circle-{{selectcss(document.Extension)}}">

ve kod

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

Her zaman iF kelimesinden kaçının
LastTribunal

Doğrudan class niteliğini kullanmaktan kaçınmak istiyorum. Bu işlem, bu öğedeki diğer eklentiler tarafından yapılan değişikliklerin üzerine yazılır.
SimonSimCity

10

Bu çözüm benim için hile yaptı

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

8

Üçlü ifadeyi kullanabilirsiniz. Bunu yapmanın iki yolu vardır:

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

veya...

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

1
Belki daha iyi bulabilirsin: <div ng-style = "{'color': (myVariable> 100)? 'Red': 'blue'}"> </div>
Dudi

Dudi, daha iyi değilse, aynı derecede yararlı, bu yüzden @ maykel'in "üçlü ifade" cevabına ekledim. İkinize de teşekkürler!
jbobbins

7

Bir veya iki özellikten oluşan basit bir css stiline ihtiyacınız olduğunda başka bir seçenek:

Görünüm:

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

Denetleyici:

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

6

Aşağıdaki örneğe bakın

<!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'den itibaren ng-classve hatta ng-attr-classSVG öğeleriyle başarısız oluyor (Sınıf özniteliğinin içindeki normal bağlamayla bile daha önce çalıştılar )

Özellikle, bunların hiçbiri şu anda çalışmıyor:

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

Geçici bir çözüm olarak kullanmalıyım

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

ve sonra stil kullanarak

[otherAttr='active'] {
   ... styles ...
}

1

Stili koşullu olarak uygulamanın (gelecekte) bir başka yolu da koşullu olarak kapsamlandırılmış stil oluşturmaktır

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

</style>

Ancak günümüzde yalnızca FireFox kapsam dahilindeki stilleri desteklemektedir.


1

Son zamanlarda bazı insanların yararlı bulabileceği bir seçenek daha var, çünkü bir stil öğesinde bir CSS kuralını değiştirmenize izin veriyor - böylece ng-tarzı, ng-sınıfı, ng-show, ng-hide, ng-animate ve diğerleri.

Bu seçenek, bir denetleyici tarafından ayarlanan ve "özel stil" olarak adlandırdığım öznitelik yönergesi tarafından izlenen hizmet değişkenlerine sahip bir hizmetten yararlanır. Bu strateji birçok farklı şekilde kullanılabilir ve bu kemanla ilgili genel bir rehberlik sağlamaya çalıştım .

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

iyi, doğru veya yanlış döndüren bir işlevle kontrol cihazınızdaki durumu kontrol etmenizi öneririm .

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

ve kontrol cihazınızda durumu kontrol edin

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

0

İzlenmesi gereken bir şey - CSS stilinde tire varsa - bunları kaldırmanız gerekir. Ayarlamak istiyorsanız background-color, doğru yol:

ng-style="{backgroundColor:myColor}" 

5
Hayır, zorunda değilsin. ng-style = "{'background-color': myColor}" mükemmel çalışıyor.
gerasalus

0

Devre dışı bırakılan bir düğmeye koşullu olarak gri metin stilini nasıl uyguladığım aşağıda açıklanmıştır

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

Çalışan bir örnek:
https://stackblitz.com/edit/example-conditional-disable-button?file=src%2Fapp%2Fapp.component.html

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.