AngularJS'nin ng seçeneklerini kullanarak seçme ile çalışma


442

Diğer yayınlarda okudum, ama anlayamadım.

Bir dizim var,

$scope.items = [
   {ID: '000001', Title: 'Chicago'},
   {ID: '000002', Title: 'New York'},
   {ID: '000003', Title: 'Washington'},
];

Bunu şu şekilde yapmak istiyorum:

<select>
  <option value="000001">Chicago</option>
  <option value="000002">New York</option>
  <option value="000003">Washington</option>
</select>

Ayrıca ID = 000002 ile seçeneği seçmek istiyorum.

Seçimi okudum ve denedim, ama anlayamıyorum.


Select2'yi kullanmanızı kesinlikle tavsiye ederim , çünkü bu sizin için halledecektir. AngularJS için bir direktif bile var .
hewstone


Aslında QuantumUI tarafından geliştirilen saf bir AngularJS çözümü var . Http://quantumui.org/ adresinde daha fazla örnek ve belge bulabilirsiniz .
Ramon Drunce

Yanıtlar:


799

Dikkat edilmesi gereken bir şey, ngOptions'ın çalışması için ngModel'in gerekli olduğudur ... ng-model="blah""$ scope.blah öğesini seçilen değere ayarla" ifadesine dikkat edin.

Bunu dene:

<select ng-model="blah" ng-options="item.ID as item.Title for item in items"></select>

AngularJS'nin belgelerinden daha fazla bilgi (daha önce görmediyseniz):

dizi veri kaynakları için:

  • dizideki değer etiketi
  • dizideki değer için etiket olarak seç
  • dizideki değere göre grupla etiketle = dizideki değere göre grupla grupla seç

nesne veri kaynakları için:

  • nesnede (anahtar, değer) etiketi
  • nesnede (anahtar, değer) için etiket olarak seç
  • nesnede (anahtar, değer) için gruplandırma etiketi
  • nesnede (anahtar, değer) için gruplara göre etiket grubu olarak seç

AngularJS'deki seçenek etiketi değerleri hakkında bazı açıklamalar için:

Kullandığınızda ng-options, ng-options tarafından yazılan seçenek etiketlerinin değerleri her zaman seçenek etiketinin ilgili dizi öğesinin dizini olacaktır . Bunun nedeni, AngularJS'nin aslında sadece ilkel türler değil, belirli kontrollerle tüm nesneleri seçmenize izin vermesidir. Örneğin:

app.controller('MainCtrl', function($scope) {
   $scope.items = [
     { id: 1, name: 'foo' },
     { id: 2, name: 'bar' },
     { id: 3, name: 'blah' }
   ];
});
<div ng-controller="MainCtrl">
   <select ng-model="selectedItem" ng-options="item as item.name for item in items"></select>
   <pre>{{selectedItem | json}}</pre>
</div>

Yukarıdaki, tüm nesneyi $scope.selectedItemdoğrudan seçmenize izin verecektir . Mesele şu ki, AngularJS ile seçenek etiketinizde ne olduğu konusunda endişelenmenize gerek yok. AngularJS bunu halletsin; sadece modelinizde nelerin bulunduğuna dikkat etmelisiniz.

Yukarıdaki davranışı gösteren ve yazılan HTML'yi gösteren bir dalgıç


Varsayılan seçenekle ilgilenmek:

Varsayılan seçenekle ilgili olarak yukarıda bahsetmediğim birkaç şey var.

İlk seçeneği seçme ve boş seçeneği kaldırma:

Bunu, tekrarladığınız öğelerdeki ilk öğeye ng-initmodeli (itibaren ng-model) ayarlayan bir basit ekleyerek yapabilirsiniz ng-options:

<select ng-init="foo = foo || items[0]" ng-model="foo" ng-options="item as item.name for item in items"></select>

Not: Bu foo"falsy" bir şeye düzgün bir şekilde başlatılması durumunda biraz deli olabilir . Bu durumda foo, büyük olasılıkla denetleyicinizde başlatılmasını işlemek isteyeceksiniz .

Varsayılan seçeneği özelleştirme:

Bu biraz farklı; burada yapmanız gereken tek şey, boş bir değer özelliğiyle seçtiğiniz bir alt öğe olarak bir seçenek etiketi eklemek ve ardından iç metnini özelleştirmek:

<select ng-model="foo" ng-options="item as item.name for item in items">
   <option value="">Nothing selected</option>
</select>

Not: Bu durumda, farklı bir seçenek seçtikten sonra bile "boş" seçeneği orada kalacaktır. AngularJS altındaki seçimlerin varsayılan davranışı için durum böyle değildir.

Bir seçim yapıldıktan sonra gizlenen özelleştirilmiş bir varsayılan seçenek:

Bir değer seçtikten sonra özelleştirilmiş varsayılan seçeneğinizin kaybolmasını istiyorsanız, varsayılan seçeneğinize bir ng-hide özelliği ekleyebilirsiniz:

<select ng-model="foo" ng-options="item as item.name for item in items">
   <option value="" ng-if="foo">Select something to remove me.</option>
</select>

3
Bunların değerlerin endeksleri olduğu ortaya çıkıyor, açısal seçim kutunuzun değeri olarak nesneleri kullanmanıza nasıl izin verebilir. Angular, seçim kutuları ile sahnelerin arkasında sizin için çok şey yapıyor ve seçeneklerinizdeki değer özelliği hakkında endişelenmeniz gerekmiyor.
Ben Lesh

1
Belgeler sitesinde "seç" altında: docs.angularjs.org/api/ng.directive:select
Ben Lesh

25
"... ngModel, ngOptions'ın çalışması için gerekli ..." benim için sorunun kaynağıydı. İyi cevap.
tristanm

1
İlk boş seçeneği ( <option value="?" selected="selected"></option>) kullanmaktan kaçınmak mümkün mü ?
Eylül'de swenedo

4
Son durumda ( bir seçim yapıldıktan sonra gizlenen özelleştirilmiş bir varsayılan seçenek) kullanmaya çalışıyorum ama bazı sorunlar bulundu. Bunun yerine, başka bir seçenek seçildiğinde varsayılan boş seçeneği gizlemek ng-if="foo"için kullanmak zorunda kaldım ng-if=!foo. Ayrıca, varsayılan boş seçenek her zaman birleşik giriş listesinin altında görünür. Birleşik listenin başına nasıl koyabilirim?
Fran Herrero

90

AngularJS öğreniyorum ve seçim ile de uğraşıyordum. Bu sorunun zaten cevaplandığını biliyorum, ama yine de biraz daha kod paylaşmak istedim.

Testimde iki liste kutusu var: araba markaları ve araba modelleri. Bazı marka seçilinceye kadar model listesi devre dışı bırakılır. Markalar listesindeki seçim daha sonra sıfırlanırsa ('Marka Seç' olarak ayarlanır), model liste kutusu tekrar devre dışı bırakılır ve seçimi de sıfırlanır ('Model Seç'e'). Modeller sadece kodlanmışken markalar bir kaynak olarak alınır.

JSON yapar:

[
{"code": "0", "name": "Select Make"},
{"code": "1", "name": "Acura"},
{"code": "2", "name": "Audi"}
]

services.js:

angular.module('makeServices', ['ngResource']).
factory('Make', function($resource){
    return $resource('makes.json', {}, {
        query: {method:'GET', isArray:true}
    });
});

HTML dosyası:

<div ng:controller="MakeModelCtrl">
  <div>Make</div>
  <select id="makeListBox"
      ng-model="make.selected"
      ng-options="make.code as make.name for make in makes"
      ng-change="makeChanged(make.selected)">
  </select>

  <div>Model</div>
  <select id="modelListBox"
     ng-disabled="makeNotSelected"
     ng-model="model.selected"
     ng-options="model.code as model.name for model in models">
  </select>
</div>

controllers.js:

function MakeModelCtrl($scope)
{
    $scope.makeNotSelected = true;
    $scope.make = {selected: "0"};
    $scope.makes = Make.query({}, function (makes) {
         $scope.make = {selected: makes[0].code};
    });

    $scope.makeChanged = function(selectedMakeCode) {
        $scope.makeNotSelected = !selectedMakeCode;
        if ($scope.makeNotSelected)
        {
            $scope.model = {selected: "0"};
        }
    };

    $scope.models = [
      {code:"0", name:"Select Model"},
      {code:"1", name:"Model1"},
      {code:"2", name:"Model2"}
    ];
    $scope.model = {selected: "0"};
}

27
Sayın rastgele kullanıcı. Bu soru ve cevabı oldukça basit ve karmaşık olmasa da, kodunuzu uygun ve ilgili konumlara (denetleyici, hizmet, şablon, veri) yerleştirmeniz, AngularJS'in şıklığını en basit ve varsayılan biçiminde gösterir. Harika bir örnek.
Atticus

1
Kullanılması gereken bu değildir. kapsamınızla ilgili olmayan başka bir değişkeni ng-modelişaret etmelidir . Docs.angularjs.org/api/ng/directive/ng adresindeki örneğe bakınmake
Dmitri Zaitsev

@DmitriZaitsev Sanırım yanılıyorsunuz, çünkü açısal dokümanlar bunu tarif ettiğiniz şekilde gösteriyor çünkü tek yol bu değil. Bize yeni başlayanlar için harika bir örnek almak yerine neden bu şekilde kullanılmaması gerektiğini düşündüğünüzü gösterin.
JRT

39

Nedense AngularJS kafamı karıştırabilir. Belgeleri bu konuda oldukça korkunç. Varyasyonlara daha iyi örnekler memnuniyetle karşılanacaktır.

Her neyse, Ben Lesh'un cevabında ufak bir değişiklik var.

Veri koleksiyonlarım şöyle:

items =
[
   { key:"AD",value:"Andorra" }
,  { key:"AI",value:"Anguilla" }
,  { key:"AO",value:"Angola" }
 ...etc..
]

şimdi

<select ng-model="countries" ng-options="item.key as item.value for item in items"></select>

yine de seçenek değerinin dizin (0, 1, 2, vb.) olmasına neden oldu.

Parça Ekleme Benim için düzeltti:

<select ng-model="blah" ng-options="item.value for item in items track by item.key"></select>

Seçim listesine bir dizi nesne eklemek istediğiniz daha sık olduğunu düşünüyorum, bu yüzden bunu hatırlayacağım!

AngularJS 1.4'ten ng seçeneklerini artık kullanamayacağınızı, ancak ng-repeatseçenek etiketinizde kullanmanız gerektiğini unutmayın:

<select name="test">
   <option ng-repeat="item in items" value="{{item.key}}">{{item.value}}</option>
</select>

3
Bu cevap sorunun tam olarak sorduğu soru gibi görünüyor. Diğer her cevap, okuyucuya hangi HTML'nin oluşturulduğunu düşünmemesini söyler, ancak select öğesi bir formdaysa, çok endişelenirim. Mükemmel cevap!
Keith

3
Bunun, sadece anahtarın değil, seçilen tam nesnenin modelde saklandığına dikkat edilmelidir. Yalnızca modeldeki anahtarı istiyorsanız, "item.key olarak item.value" sürümünü kullanmak istersiniz. Bu benim için önemli olan modelde istediğim verilere değil, HTML'nin neye benzediğine asıldığım için beni bir süre karıştırdı.
mhenry1384

@ mhenry1384 Evet haklısın, tüm nesneyi saklamak için. Aslında bu özelliği seviyorum çünkü size sadece kimliğe erişmenize izin veriyor (ihtiyacınız varsa.). Mongo koleksiyonu ile listeleri doldururken ve seçilen öğeden bazı özelliklere ihtiyacım olduğunda benim için iyi çalışıyor.
Mattijs

2
Ve içindeki "ng-change" ile değişiklikleri nasıl tespit edebiliriz option?
Konstantinos Natsios

2
Güncelleme ile ilgili olarak, bu doğru görünmüyor. ng-seçenekleri 1.5'te hala iyi çalışıyor. Aynı zamanda dokümantasyonda hala gösterilmektedir. docs.angularjs.org/api/ng/directive/select
Jeremy A. West

15

Soru zaten cevaplandı (BTW, Ben tarafından sağlanan gerçekten iyi ve kapsamlı cevap), ancak eksiksiz olması için başka bir öğe eklemek istiyorum, ki bu da çok kullanışlı olabilir.

Ben tarafından önerilen örnekte:

<select ng-model="blah" ng-options="item.ID as item.Title for item in items"></select>

Aşağıdaki ngOptions bir şekilde kullanılmaktadır: select as label for value in array.

Etiket , sonucun <option>öğe için etiket olacağı bir ifadedir . Bu durumda, daha karmaşık seçenek etiketlerine sahip olmak için belirli dize birleşimlerini gerçekleştirebilirsiniz.

Örnekler:

  • ng-options="item.ID as item.Title + ' - ' + item.ID for item in items" gibi etiketler verir Title - ID
  • ng-options="item.ID as item.Title + ' (' + item.Title.length + ')' for item in items"gibi etiketler verir Title (X)nerede, XBaşlık dizenin uzunluğudur.

Filtreleri de kullanabilirsiniz, örneğin,

  • ng-options="item.ID as item.Title + ' (' + (item.Title | uppercase) + ')' for item in items"Title (TITLE)Title özelliği ve TITLE başlık değerinin aynı değer olduğu ancak büyük harfli karakterlere dönüştürüldüğü gibi etiketler verir .
  • ng-options="item.ID as item.Title + ' (' + (item.SomeDate | date) + ')' for item in items"Title (27 Sep 2015)modelinizde bir özellik varsa size etiket verirSomeDate

7

CoffeeScript'te:

#directive
app.directive('select2', ->
    templateUrl: 'partials/select.html'
    restrict: 'E'
    transclude: 1
    replace: 1
    scope:
        options: '='
        model: '='
    link: (scope, el, atr)->
        el.bind 'change', ->
            console.log this.value
            scope.model = parseInt(this.value)
            console.log scope
            scope.$apply()
)
<!-- HTML partial -->
<select>
  <option ng-repeat='o in options'
          value='{{$index}}' ng-bind='o'></option>
</select>

<!-- HTML usage -->
<select2 options='mnuOffline' model='offlinePage.toggle' ></select2>

<!-- Conclusion -->
<p>Sometimes it's much easier to create your own directive...</p>

1
Unutmak Dont radixiçin parseInt: http://davidwalsh.name/parseint-radix
GFoley83

6

Her seçenek için özel bir başlığa ihtiyacınız varsa ng-optionsgeçerli değildir. Bunun yerine ng-repeatseçeneklerle birlikte kullanın :

<select ng-model="myVariable">
  <option ng-repeat="item in items"
          value="{{item.ID}}"
          title="Custom title: {{item.Title}} [{{item.ID}}]">
       {{item.Title}}
  </option>
</select>

3

Umarım aşağıdakiler sizin için çalışır.

<select class="form-control"
        ng-model="selectedOption"
        ng-options="option.name + ' (' + (option.price | currency:'USD$') + ')' for option in options">
</select>

1

Yararlı olabilir. Bağlamalar her zaman işe yaramaz.

<select id="product" class="form-control" name="product" required
        ng-model="issue.productId"
        ng-change="getProductVersions()"
        ng-options="p.id as p.shortName for p in products"></select>

Örneğin, bir REST hizmetinden seçenekler listesi kaynak modelini doldurursunuz. Listeyi doldurmadan önce seçilen bir değer biliniyordu ve ayarlandı. $ Http ile REST isteği yürütüldükten sonra liste seçeneği yapılır.

Ancak seçilen seçenek ayarlanmamış. Bilinmeyen nedenlerden dolayı, gölge $ digest yürütmesindeki AngularJS seçili olması gerektiği gibi bağlanmıyor. Seçilen ayarlamak için jQuery kullanmak zorunda. Bu önemli! AngularJS, gölgede, ng yineleme seçeneklerinin ürettiği attr "değeri" değerine önek ekler. İnt için "sayı:" dır.

$scope.issue.productId = productId;
function activate() {
    $http.get('/product/list')
       .then(function (response) {
           $scope.products = response.data;

           if (productId) {
               console.log("" + $("#product option").length);//for clarity
               $timeout(function () {
                   console.log("" + $("#product option").length);//for clarity
                   $('#product').val('number:'+productId);

               }, 200);
           }
       });
}
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.