2013-03-07 48 views
33

我個人的對象數組如何使用納克級的選擇與NG選項

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

,我使用選擇與NG選項是這樣的:

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

我想以顯示記錄合格:虛假紅色顏色。 所以問題是我如何使用ng-classselect爲了達到這個目的?由於我們沒有使用任何option標籤,因此如果我簡單地在select元素本身中添加ng-class,它將無法正常工作。

+0

使用指令循環選項,並將類應用於選項標籤,滿足條件 – charlietfl 2013-03-07 06:46:54

+0

是的,我可以做到這一點,但沒有任何方式直接做到這一點?我的意思是在這裏必須有一種方法來使用ng-class。 – 2013-03-07 08:12:10

+0

供參考:我已經更新了我的答案,因爲它有一些錯誤。不知道這是否會影響當前代碼庫中的任何內容,但是如果您在使用之前發佈的內容,可能需要查看一下。 – 2013-11-30 03:18:16

回答

30

您可以創建一個指令,在處理ngOptions指令後處理這些選項,並使用相應的類更新它們。

更新:舊的代碼有一些錯誤,自從我回答了這個問題後,我學到了一些東西。 Here is a Plunk that was redone in 1.2.2 (but should work in 1.0.X as well)

下面是更新代碼:

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> 

它就像納克級呢,不同之處在於它在每個項目收集的基礎上。

+1

這是一個很好的解決方案使用。總有一些指令可以挽救一天! :D +1 – 2013-03-08 03:38:29

+1

這是一個有趣的想法。我喜歡參加創建新範圍的地方,並將其與我正在研究的孩子一起擴展,以便我可以評估它!所以Angular非常有角度。當我編碼時,讓我想要發出激光聲音... pew pew pew。 – 2013-03-08 18:08:28

+0

blesh,你的指令無法正常工作。在選擇任何

12

在這種情況下,你只能申請納克級只有在使用ng-repeat與選項標籤:

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

這將使自定義類到您的「合格」的人,但CSS不會一致地工作bowsers。

Plunker

+1

這個工程,但我想用ng選項,因爲這不會讓任何值選擇一次,我將它保存在我的數據庫並刷新它。你有什麼想法如何保持我的紀錄選擇?我已經使用ng選擇了這個,但是也不會工作 – 2013-03-07 10:30:01

+0

這不是問題。我將Plunker鏈接附加到答案上。 – Stewie 2013-03-07 10:38:37

+0

謝謝你!我正在使用相同的東西。只有不同的是我使用jQuery版本-1.7,因此它不支持ng選擇。改變了版本參考,它的作品奇蹟! – 2013-03-07 12:18:19

3

該指令是一種方式,但我使用了自定義過濾器。 如果你知道如何選擇你的元素,你應該沒問題。挑戰在於找到選擇內的當前選項元素。我可以使用「包含」選擇器,但選項中的文本可能不是唯一的項目。要按價值查找選項,我注入了範圍和項目本身。

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

在這裏,您可以see it work

+1

實際上只是將項目集合發送到過濾器(通過您的範圍對象)。使用像這樣的索引 對於項目中的(idx,item)項目,您可以刪除$。如果你的收藏很大,這可能會造成浪費。你的元素找到現在這個 - var elem = angular.element(「select> option [value ='」+ opt.ix +「']」); 感謝您的回答,我最終使用它與我的國防部。 – Craig 2014-11-25 03:04:06

+0

是的,你說得對,謝謝你的建議。正如我提出的那樣,我並不知道,通常過濾器的價格是多少,通過參數注入的範圍並不是最佳實踐的一部分。 – westor 2014-11-25 16:36:34

+0

我不會爲此使用過濾器。通常過濾器也需要在服務和控制器中使用。做DOM操作打破了這一點。指令是爲此而設計的。 – Dormouse 2014-12-15 11:15:25

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; 
} 
+0

謝謝!我會試試這個。 – 2014-09-23 09:02:35

+0

這是否會觸發重複的項目錯誤,因爲符合條件的項目必須是唯一的?所以這不會工作布爾以外的數據(是/否選擇)。 – Dormouse 2014-12-15 11:12:40

+0

適用於某些數據類型的簡單解決方案。 – chris22smith 2017-01-23 11:14:28

4

我想評論接受的答案,但因爲我沒有足夠的聲望點,我必須添加一個答案。 我知道這是一個老問題,但最近添加到接受的答案的評論。

對於angularjs 1.4.x,建議的指令必須進行調整以使其再次工作。 由於ngOptions斷裂的變化,期權的價值已不再索引,因此行

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

將不再工作。

如果在plunker更改代碼以

<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

我也試過用在NG-選項track by,但沒有得到它的工作。 也許有更多的經驗,在angularjs然後我(=我的第一個項目在angularjs)?

2

由於聲譽的原因,我無法將其作爲評論來撰寫,但我已經更新了與Angular 1.4.8一起使用的公開答案。感謝Ben Lesh提供的原始答案,這對我有很大的幫助。所不同的似乎是較新的角度產生的選項是這樣的:

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

所以代碼

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

將無法​​找到的選項。我的更改解析了ngOptions並確定了該標籤使用的項目的哪個字段,並根據該選項找到了代替值的選項。請參閱:

http://plnkr.co/edit/MMZfuNZyouaNGulfJn41

2

如果你既想顯示他們在紅顏色,但防止用戶選擇的選項,你可以使用disable when

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

然後,您可以使用CSS設置禁用選項的顏色。

2

我知道我有點遲到了,但誰不想用純CSS來解決這個問題,不使用指令的人,你可以做一個CSS類是這樣的:

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

這個CSS規則說:找到所有具有值=假的標籤名稱爲'選項'的每個'選擇'中有一個類「blueSelect」,並使文本顏色#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選項裏面的曲目是什麼將舉行什麼來跟蹤的選項,或「值「每個選項的字段。請注意,根據您的項目需求,您可能需要做一些調整才能按照您的要求進行此項工作。

但是,如果有多個選項具有相同的「合格」字段值,那麼這種方法無法正常工作。因此,爲了實現這一點,我們創建了一個複合表達式來跟蹤,這樣我們就可以在每個選項中擁有唯一的值來跟蹤。在這種情況下,我們結合這兩個字段名稱和符合條件的

所以,現在我們的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選項表達,例如:

標籤禁用時禁用陣列軌道由trackexpr

我會留下怎樣使用你的情況爲你找出;-)

這適用於簡單的CSS的修改,對於更復雜的東西,你可能需要一個指令或其他方法。測試鉻。

我希望這可以幫助一個人在那裏。 :-)