41

Personオブジェクトの配列があります

var persons = [
{Name:'John',Eligible:true},
{Name:'Mark',Eligible:true},
{Name:'Sam',Eligible:false},
{Name:'Edward',Eligible:false},
{Name:'Michael',Eligible:true}
];

そして私は次のようなng-optionsでselectを使用しています:

<select ng-model="Blah" ng-options="person.Name for person in persons"></select>

Eligible:falseのレコードを赤い色で表示したいと思います。だから問題は、これを達成するためにどのようにng-classinを使用するのですか?タグselectを使用していないため、要素自体を追加するだけでは機能しません。optionng-classselect

4

9 に答える 9

36

適切なクラスでオプションを更新するngOptionsディレクティブが処理された後に、オプションを処理するディレクティブを作成できます。

更新:古いコードにはいくつかのバグがあり、この質問に答えてから少し学びました。これは1.2.2でやり直されたプランクです(ただし、1.0.Xでも機能するはずです)

コードが更新されました(2013年11月30日3時17分) 。

app.directive('optionsClass', function ($parse) {
  return {
    require: 'select',
    link: function(scope, elem, attrs, ngSelect) {
      // get the source for the items array that populates the select.
      var optionsSourceStr = attrs.ngOptions.split(' ').pop(),
      // use $parse to get a function from the options-class attribute
      // that you can use to evaluate later.
          getOptionsClass = $parse(attrs.optionsClass);

      scope.$watch(optionsSourceStr, function(items) {
        // when the options source changes loop through its items.
        angular.forEach(items, function(item, index) {
          // evaluate against the item to get a mapping object for
          // for your classes.
          var classes = getOptionsClass(item),
          // also get the option you're going to need. This can be found
          // by looking for the option with the appropriate index in the
          // value attribute.
              option = elem.find('option[value=' + index + ']');

          // now loop through the key/value pairs in the mapping object
          // and apply the classes that evaluated to be truthy.
          angular.forEach(classes, function(add, className) {
            if(add) {
              angular.element(option).addClass(className);
            }
          });
        });
      });
    }
  };
});

マークアップでの使用方法は次のとおりです。

<select ng-model="foo" ng-options="x.name for x in items" 
        options-class="{ 'is-eligible' : eligible, 'not-eligible': !eligible }">
</select>

コレクション内のアイテムごとであることを除いて、ng-classと同じように機能します。

于 2013-03-07T18:03:16.543 に答える
15

ng-repeatこのシナリオでは、オプションタグとともに使用する場合にのみng-classを適用できます。

<select ng-model="Blah">
  <option ng-repeat="person in persons" ng-class="{red: person.Eligible}">
    {{person.Name}}
  </option>  
</select>

これにより、「適格」な人にカスタムクラスが提供されますが、CSSはバウザー間で一貫して機能しません。

プランカー

于 2013-03-07T10:12:17.900 に答える
4

受け入れられた回答についてコメントしたかったのですが、評判ポイントが足りないため、回答を追加する必要があります。これは古い質問であることは知っていますが、最近受け入れられた回答にコメントが追加されました。

anglejs 1.4.xの場合、提案されたディレクティブを再度機能させるように適合させる必要があります。ngOptionsの重大な変更により、オプションの値はインデックスではなくなったため、行

option = elem.find('option[value=' + index + ']');

もう動作しません。

プランカーのコードをに変更した場合

<select ng-model="foo" ng-options="x.id as x.name for x in items" 
        options-class="{ 'is-eligible' : eligible, 'not-eligible': !eligible }">
</select>

その結果、オプションタグの値は次のようになります。

value="number:x"(xはアイテムオブジェクトのIDです)

ディレクティブをに変更します

option = elem.find('option[value=\'number:' + item.id + '\']');

それを再び機能させるために。

もちろん、これは一般的な解決策ではありません。オブジェクトにIDがない場合はどうなるでしょうか。次にvalue="object:y"、オプションタグにyがangularjsによって生成された数値であることがわかりますが、これyを使用すると、アイテムにマップできません。

これが、angularjsを1.4.xに更新した後、一部の人々がコードを再び機能させるのに役立つことを願っています

track byinも使おうとしましng-optionsたが、うまくいきませんでした。たぶん、angularjsの経験が私よりも多い人(=angularjsの最初のプロジェクト)?

于 2015-12-11T12:35:25.283 に答える
3

ディレクティブは一方向ですが、カスタムフィルターを使用しました。要素の選択方法を知っている場合は、ここで問題ないはずです。課題は、select内の現在のオプション要素を見つけることでした。「含む」セレクターを使用することもできますが、オプションのテキストはアイテムごとに一意ではない可能性があります。値でオプションを見つけるために、スコープとアイテム自体を挿入しました。

<select ng-model="foo" ng-options="item.name|addClass:{eligible:item.eligible,className:'eligible',scope:this,item:item} for item in items"></select>

とjsで:

var app = angular.module('test', []);

app.filter('addClass', function() {
  return function(text, opt) {
    var i;
    $.each(opt.scope.items,function(index,item) {
      if (item.id === opt.item.id) {
        i = index;
        return false;
      }
    });
    var elem = angular.element("select > option[value='" + i + "']");
    var classTail = opt.className;
    if (opt.eligible) {
      elem.addClass('is-' + classTail);
      elem.removeClass('not-' + classTail);
    } else {
      elem.addClass('not-' + classTail);
      elem.removeClass('is-' + classTail);
    }
    return text;
  }
})

app.controller('MainCtrl', function($scope) {
  $scope.items = [
    { name: 'foo',id: 'x1',eligible: true},
    { name: 'bar',id: 'x2',eligible: false}, 
    { name: 'test',id: 'x3',eligible: true}
  ];
 });

ここでそれが機能するのを見ることができます。

于 2013-11-22T09:37:26.887 に答える
3

受け入れられた答えは私にはうまくいきませんでした、それで私は以下を使用するカスタムディレクティブのない代替案を見つけましたtrack by

<select ng-model="foo" ng-options="x.name for x in items track by x.eligible"></select>

各オプションは、値x.eligibleを取得します。CSSでは、value = trueでオプションのスタイルを設定できます(trueは文字列である必要があると思います)。CSS:

option[value="true"]{
    color: red;
}
于 2014-09-23T08:25:37.460 に答える
3

それらを赤い色で表示するだけでなく、ユーザーがオプションを選択できないようにする場合は、次を使用できますdisable when

<select 
    ng-model="Blah"
    ng-options="person.Name disable when !person.Eligible for person in persons">
</select>

次に、CSSを使用して、無効になっているオプションの色を設定できます。

于 2016-04-12T14:27:31.813 に答える
2

評判のため、これをコメントとして書くことはできませんが、Angular 1.4.8で動作するように、受け入れられた回答のプランカーを更新しました。元の答えをくれたBenLeshに感謝し、それは私を大いに助けてくれました。違いは、新しいAngularが次のようなオプションを生成することです。

<option class="is-eligible" label="foo" value="object:1">foo</option>

だからコード

option = elem.find('option[value=' + index + ']');

オプションを見つけることができません。私の変更はngOptionsを解析し、ラベルに使用されたアイテムのフィールドを判別し、値ではなくそれに基づいてオプションを見つけます。見る:

http://plnkr.co/edit/MMZfuNZyouaNGulfJn41

于 2016-02-04T06:16:20.043 に答える
2

私はパーティーに少し遅れていることを知っていますが、ディレクティブを使用せずに純粋なCSSでこれを解決したい人のために、次のようなcssクラスを作成できます。

select.blueSelect option[value="false"]{
    color:#01aac7;
}

このcssルールは次のように述べています。クラス「blueSelect」を持つすべての「select」内のタグ名「option」でvalue=falseのすべての要素を検索し、テキストの色を#01aac7にします。(青の色合い)

あなたの場合、HTMLは次のようになります。

<select class="form-control blueSelect" name="persons" id="persons1"
        ng-options="person as person.name for person in $ctrl.persons track by person.Eligible"
        ng-model="$ctrl.selectedPerson" required>
    <option disabled selected value="">Default value</option>
</select>

ng-options内の追跡は、オプションを追跡する対象、または各オプションの「値」フィールドを保持するものです。プロジェクトのニーズによっては、要件に応じてこれを機能させるために微調整が必​​要になる場合があることに注意してください。

ただし、[適格]フィールドに同じ値のオプションが複数ある場合は、正しく機能しません。したがって、これを機能させるために、追跡する複合式を作成します。これにより、各オプションで追跡する一意の値を設定できます。この場合、NameフィールドとEligibleフィールドの両方を組み合わせます

これで、htmlは次のようになります

<select class="form-control blueSelect" name="persons" id="persons2"
        ng-options="person as person.name for person in $ctrl.persons track by (person.name + person.Eligible)"
        ng-model="$ctrl.selectedPerson" required>
    <option disabled selected value="">Default value</option>
</select>

そして私たちのcss:

select.blueSelect option[value*="False"]{
    color:#01aac7;
}

値の横にある*に注意してください。これは正規表現であり、オプション要素の値フィールドのどこかに「False」という単語を見つけることを意味します。

クイック編集 ng-options式の「disablewhen」を使用して、Eligible=Falseでオプションを無効にすることもできます。次に例を示します。

trackexprによる配列トラックの無効にする場合はラベルを無効にする

私はあなたが見つけるためにあなたの場合にそれを使用する方法を残します;-)

これは、単純なcssの変更で機能します。より複雑なものでは、ディレクティブまたは他のメソッドが必要になる場合があります。クロームでテスト済み。

これが誰かの助けになることを願っています。:-)

于 2016-05-24T05:12:54.240 に答える
-1

ディレクティブまたはフィルターを追加するよりも簡単な別の回避策を見つけました。これは、スタイルを適用するonfocusイベントのハンドラーを追加することです。

angular.element('select.styled').focus( function() {
  angular.element(this).find('option').addClass('myStyle');
});
于 2018-04-09T13:42:12.093 に答える