AngularJS neden seçime boş bir seçenek içeriyor?


652

AngularJS ile son birkaç haftadır çalışıyorum ve beni gerçekten rahatsız eden tek şey, tüm permütasyonları veya http://docs.angularjs.org/api/ng adresindeki spesifikasyonda tanımlanan yapılandırmayı denedikten sonra bile .directive: select , select öğesinin ilk alt öğesi olarak hala boş bir seçenek alıyorum.

İşte Yeşim:

select.span9(ng-model='form.type', required, ng-options='option.value as option.name for option in typeOptions');

İşte denetleyici:

$scope.typeOptions = [
    { name: 'Feature', value: 'feature' },
    { name: 'Bug', value: 'bug' },
    { name: 'Enhancement', value: 'enhancement' }
];

Son olarak, oluşturulan HTML şu şekildedir:

<select ng-model="form.type" required="required" ng-options="option.value as option.name for option in typeOptions" class="span9 ng-pristine ng-invalid ng-invalid-required">
    <option value="?" selected="selected"></option>
    <option value="0">Feature</option>
    <option value="1">Bug</option>
    <option value="2">Enhancement</option>
</select>

Ondan kurtulmak için ne yapmam gerekiyor?

Not: İşler bu olmadan da çalışır, ancak select2'yi birden fazla seçim yapmadan kullanırsanız tuhaf görünür.

Yanıtlar:


646

Boş option, tarafından başvurulan bir değer ng-modeliletilen bir seçenekler kümesinde yoksa oluşturulur ng-options. Bu, yanlışlıkla model seçimini önlemek için olur: AngularJS, başlangıç ​​modelinin seçenekler kümesinde tanımsız olduğunu veya tanımlanmadığını görebilir ve model değerine kendi başına karar vermek istemez.

Boş seçenekten kurtulmak istiyorsanız, kontrol cihazınızda bir başlangıç ​​değeri seçin, şuna benzer:

$scope.form.type = $scope.typeOptions[0].value;

İşte jsFiddle: http://jsfiddle.net/MTfRD/3/

Kısacası: boş seçenek, geçerli bir modelin seçilmediği anlamına gelir (geçerli olarak demek istediğim: seçenekler kümesinden). Bu boş seçenekten kurtulmak için geçerli bir model değeri seçmeniz gerekir.


7
Hem $ scope.form.type = '' ile denedim; ve $ scope.form.type = $ scope.typeOptions [0], ancak yine de bunu görüyorum - <seçenek değeri = "?" seçilmiş = "seçildi"> </option>
Sudhanshu

5
Bazen bu verilerin JS'de olması gerçekten mantıklı değildir. Bu seçimde ne olduğuna karar veren sunucu buysa, neden JS bunu çoğaltmalıdır?
heneryville

11
Bir dizi kullanıyorsanız ve nulldeğerlerinizden biri ise bu maalesef çalışmaz .
vpiTriumph

6
Boş içine bir metin eklemek mümkün mü <option>tat açısal gibi bir şey üretti<option value="?">Select an option</option>
RPDeshaies

3
@ Tareck117 sadece <option value="">Select an option</option>wirte bu seçenek listesinin null-Değeri. Gerek yok? -Karakter.
Sebastian

235

Bir başlangıç ​​değeri istiyorsanız, @ pkozlowski.opensource'un cevabına bakın; ng-init kullanarak görünümde (denetleyiciden ziyade) FYI de uygulanabilir:

<select ng-model="form.type" required="required" ng-init="form.type='bug'"
  ng-options="option.value as option.name for option in typeOptions" >
</select>

Başlangıç ​​değeri istemiyorsanız, "boş bir dizeye ayarlanmış değeri olan tek bir sabit kodlu öğe, öğenin içine yerleştirilebilir. Bu öğe, null veya" seçili olmayan "seçeneği" temsil eder:

<select ng-model="form.type" required="required"
  ng-options="option.value as option.name for option in typeOptions" >
    <option style="display:none" value="">select a type</option>
</select>

4
@hugo, working fiddle: jsfiddle.net/4qKyx/1 "Bir tür seçin" ifadesinin gösterildiğini, ancak bununla ilişkili bir değer olmadığını unutmayın. Ve başka bir şey seçtiğinizde, bir daha göremezsiniz. (Chrome'da test edin.)
Mark Rajcok

1
@MarkRajcok - mükemmel öneri! Ben transclude direktifi ile örnek kullanarak başka bir konuda tökezledi. Lütfen bir göz atar mısın? plnkr.co/edit/efaZdEQlNfoDihk1R1zc?p=preview
Jan-Terje Sørensen


2
Bu şimdilik işe yarayabilir, ancak açısal belgeler özellikle ng-init dışında herhangi bir şey için ng-init kullanılmasını öneriyor - bkz. Docs.angularjs.org/api/ng/directive/ngInit
Ed Norris

3
IE10'da çalışmaz, "bir tür seçin" her zaman görünür ve seçilebilir.
Robin

121

Açısal <1.4

Orada "null" seçeneklerinden biri için geçerli bir değer olarak davranan herkes için (bu yüzden "null" öğesinin, aşağıdaki örnekte typeOptions içindeki ), otomatik olarak eklendiğinden emin olmanın en basit yolunu buldum seçeneği gizli ise ng-if kullanmaktır.

<select ng-options="option.value as option.name for option in typeOptions">
    <option value="" ng-if="false"></option>
</select>

Neden ng-if ve ng-hide değil? Yukarıdaki içindeki ilk seçeneği hedefleyecek css seçicilerinin, gizli olanı değil, "gerçek" seçeneği hedeflemeyi seçmesini istediğiniz için. İletkiyi e2e testi için kullandığınızda ve (herhangi bir nedenle) by.css () yöntemini kullanarak seçim seçeneklerini hedeflediğinizde kullanışlıdır.

Açısal> = 1.4

Seçme ve seçenek yönergelerinin yeniden düzenlenmesi nedeniyle, ng-ifkullanım artık uygun bir seçenek değildir, bu nedenle ng-show="false"yeniden çalışması için dönmeniz gerekir.


5
Kabul edilen cevap olmalı, çünkü bu seçim için doğru görsel davranış. size="5"Seçme niteliklerine koyarsınız ve seçilen hiçbir şeyin olmadığını görebilirsiniz! Bir varsayılan gibi <select>-Element! Açısalın neden multiple
Sebastian

1
Evet katılıyorum, bu kabul edilen cevap olmalı. Bu 'açısal yol'dur. ng-if aslında seçenekler öğesini dom'dan kaldırır (false olduğunda), bu çözüm 'hacky' kodlaması olmayan tüm tarayıcılarda da çalışır (ng-hide veya ng-show'un aksine).
Sander_P

2
@Sander_P tanım gereği bu çözüm bence "hacky" kodlamasıdır (dom'a bir şeyi açarak kandırmak için bir şey koymak), ama haklısın hala "en iyi" çözüm. "Daha da iyi" çözüm, değeri olmayan bir friggin seçimine izin vermek olacaktır! Ne halt? Bu bir uç senaryo gibi değil.
dudewad

@dudewad: Angular 1.4 ile işler daha iyi sonuç verebilir. 1.4.0 için AngularJS blogundan: "ngOptions bir dizi can sıkıcı hatanın düzeltilmesine izin vermek için tamamen yeniden düzenlendi"
Sander_P

1
Haha "sinir bozucu böcekler". Tamam. Teslimattan 3 gün önce yükseltme söz konusu olduğunda hala biraz titizim, bu yüzden şu an için çözümünüzü koruyacağım, bu da yüzüyor gibi görünüyor. Geleceğe rağmen not :) Teşekkürler!
dudewad

36

Belki birisi için yararlıdır:

Ng seçenekleri yerine düz seçenekler kullanmak istiyorsanız, aşağıdakileri yapabilirsiniz:

<select ng-model="sortorder" ng-init="sortorder='publish_date'">
  <option value="publish_date">Ascending</option>
  <option value="-publish_date">Descending</option>
</select>

Modeli satır içi olarak ayarlayın. Boş seçeneklerden kurtulmak için ng-init kullanın


JSON dizileri yerine OBJECTS ile ng-seçenekleri kurmanın net bir örneğini bulamadım ve ikisi arasında "çevirmeye" çalıştığımda, sadece doğru değil, aynı zamanda "sessizce" başarısız oluyor Yanlış yaptığım hakkında hiçbir fikrim yok. Sonunda bir seçenek etiketinde düz ng-repeat seçtim. En iyi uygulama olmadığını biliyorum ama en azından ÇALIŞIYOR. Herkes beni açık, kolay ayrıntılar üzerinde değiştirilebilir swap, veri nesneleri (ng değil) ile ng seçenekleri kullanarak açısal-n00b dostu çalışma örneği işaret edebilir, sevinirim. Ng-init kullanıyorsa çift sevinir.
code-sushi

Düz seçenekler kullanıyorum, ancak denetleyicide seçilen açılır menü değerini almıyorum. Örn: Uyarıyı denedim ($ scope.sortorder.value); ve uyarı ($ scope.sortorder); her ikisi de tanımsız verir. Seçilen değeri buraya nasıl getirebilirim?
Maverick Riz

Bunun için çok teşekkür ederim. Denetleyiciye ihtiyacım olmayan tamamen işe yaramaz bir nesne yazmak üzereydim. Sadece basit bir seçime ihtiyacım vardı. Bir kez daha teşekkür ederim.
Muhammed bin Yusrat

22

Bana da benzer bir şey oluyordu ve açısal 1.5'e yükseltilmesinden kaynaklanıyordu. ng-initiçin ayrıştırılmıyordur edilecek görünüyor tip açısal yeni sürümlerinde. Eski Angular'da ng-init="myModelName=600""600" değerine sahip bir seçeneğe eşleme yapılır, <option value="600">First</option>ancak Angular 1.5'te 600 değerine sahip bir seçenek bulmayı umduğu için bunu bulamaz <option value=600>First</option>. Açısal daha sonra rastgele bir ilk öğe ekler:

<option value="? number:600 ?"></option>

Açısal <1.2.x

<select ng-model="myModelName" ng-init="myModelName=600">
  <option value="600">First</option>
  <option value="700">Second</option>
</select>

Açısal> 1.2

<select ng-model="myModelName" ng-init="myModelName='600'">
  <option value="600">First</option>
  <option value="700">Second</option>
</select>

1
Teşekkürler! Benim durumumda ng-init (varsayılan değer yok) kullanamazsınız, bu yüzden modelimi bir dizeye döktüm ve işe yaradı!
Rodrigo Graça

Uygulama üretim sorunum için çok yararlı. Nabil Boag
Venki

3
Bu eserler, tabii, ama daha iyi seçenekler kullanmaktır ng-value="600"içinde optionyerine value. Bir sayıya ayrıştırır ve değerlerinizi şimdi yaptığınız gibi dönüştürmeniz gerekmez :)
Max

@Max Çok yüksek değerli cevaplar denedim ama sizinkini bulana kadar hiçbiri işe yaramadı. Teşekkür ederim.
Andrew

21

Buradaki çok sayıda cevap arasında, benim için çalışan çözümü yeniden yayınlayacağımı ve aşağıdaki koşulların tümünü karşılayacağımı düşündüm :

  • ng modeli sahte olduğunda bir yer tutucu / bilgi istemi sağladı (örneğin "--seç bölge--" w. value="")
  • ng-model değeri yanlış olduğunda ve kullanıcı seçenekler açılır menüsünü açtığında yer tutucu seçilir (burada belirtilen diğer çözümler, yanıltıcı olabilecek ilk seçeneğin seçili görünmesini sağlar)
  • Kullanıcının geçerli bir değerin seçimini kaldırmasına izin verin, temel olarak sahte / varsayılan değeri tekrar seçin

resim açıklamasını buraya girin

kod

<select name="market_vertical" ng-model="vc.viewData.market_vertical"
    ng-options="opt as (opt | capitalizeFirst) for opt in vc.adminData.regions">

    <option ng-selected="true" value="">select a market vertical</option>
</select>

src

orijinal soru cevap - https://stackoverflow.com/a/32880941/1121919


Varsayılan olan <option ng-selected="true" value="null">mı demek istiyorsun ?
jusopi

Yani ng-model değeri null, açısal oluşturma ve boş seçenek olarak
ayarlanmışsa

16

Hızlı bir çözüm:

select option:empty { display:none }

Umarım birine yardımcı olur. İdeal olarak, seçilen cevap yaklaşım olmalıdır, ancak bu mümkün değilse bir yama olarak çalışmalıdır.


2
Testlerime göre bu yalnızca Chrome (üstünde yeni Chrome) ve Firefox'ta çalışacak. IE ve Safari arası. Opera ve diğer edge tarayıcıları hakkında bilmiyorum. Her iki durumda da, bu maalesef iyi bir çözüm değil .
dudewad

bunu <select> kapanışından önce html'ye veya js içine başka bir yere yerleştirmeliyiz
H Varma

1
@HVarma Bu bir CSS kuralıdır. Stil sayfasına veya <style> etiketinin içine yerleştirin
KK

@KK stackoverflow.com/questions/48355599/… Lütfen bunu kontrol edebilir misiniz?
Sudarshan Kalebere

14

Evet, ng-model özelliği tanımsız olduğunda ng-model boş seçenek değeri oluşturur. Ng-modeline nesne atarsak bundan kaçınabiliriz

Misal

açısal kodlama

$scope.collections = [
    { name: 'Feature', value: 'feature' }, 
    { name: 'Bug', value: 'bug' }, 
    { name: 'Enhancement', value: 'enhancement'}
];

$scope.selectedOption = $scope.collections[0];


<select class='form-control' data-ng-model='selectedOption' data-ng-options='item as item.name for item in collections'></select>

Önemli Not:

Ng-modeline $ scope.collections [0] veya $ scope.collections [1] gibi bir dizi nesnesi atayın, nesne özelliklerini kullanmayın. sunucudan seçenek değeri alıyorsanız, geri arama işlevini kullanarak, ng-modeline nesne atayın

Açısal belgeden NOT

Not: ngModel değerle değil referansla karşılaştırır. Bir nesne dizisine bağlanırken bu önemlidir. bir örneğe bakın http://jsfiddle.net/qWzTb/

sonunda defalarca denedim sonunda buldum.


8

Hem @ pkozlowski.opensource'un hem de @ Mark'ın cevaplarının doğru olmasına rağmen, değerinden bağımsız olarak listedeki ilk öğeyi her zaman seçtiğim biraz değiştirilmiş sürümümü paylaşmak istiyorum:

<select ng-options="option.value as option.name for option in typeOptions" ng-init="form.type=typeOptions[0].value">
</select>

4

Açısal 1.4x kullanıyorum ve bu örneği buldum, bu yüzden seçimde başlangıç ​​değerini ayarlamak için ng-init kullandım:

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

3


Aynı sorunla karşılaştım. Normal gönderi ile açısal bir form gönderiyorsanız, açısal seçenekler için değerleri ayarladığınız şekilde ayarlamanıza izin vermediğiniz için bu sorunla karşılaşacaksınız. "Form.type" değerini alırsanız, doğru değeri bulacaksınız. Açısal nesneyi kendiniz form postası olarak değil, göndermelisiniz.


3

Basit bir çözüm, boş bir değeri olan bir seçenek ayarlamaktır, ""bu ekstra tanımlanmamış seçeneği ortadan kaldırır.


5
Doenst çalışması @ 1.4.3, Sadece forma 2 boş seçenek ekler
Denny Mueller

3

Tamam, aslında cevap çok basit: Angular tarafından tanınmayan bir seçenek olduğunda, donuk olanı içerir. Yanlış yaptığınız şey, ng-options kullandığınızda bir nesneyi okuyor,[{ id: 10, name: test }, { id: 11, name: test2 }] right?

Model değerinizin eşit olarak değerlendirilmesi için gereken budur, seçilen değerin 10 olmasını istediğinizi, modelinizi { id: 10, name: test }10 seçmek gibi bir değere ayarlamanız gerektiğini , bu nedenle bu çöpü OLMAYACAKTIR.

Umarım herkesin anlamasına yardımcı olur, çalışırken zor zamanlar geçirdim :)


2

Bu çözüm benim için çalışıyor:

<select ng-model="mymodel">    
   <option ng-value="''" style="display:none;" selected>Country</option>
   <option value="US">USA</option>
</select>

Aşağı oy, seçenek öğelerine CSS uygulanmasının tüm tarayıcılarda çalışmadığı için olabilir.
Kafoso

Sadece Chrome, FireFox, Safari ve Edge'de test ettim - her şey çalışıyor.
MMM

@MMM "tüm tarayıcılar" IE içerir. Birçok kullanıcı hala IE 10 ve 11'e takılı kalıyor ve bu yüzden aşağı oylama gerçekleşti. Chrome, fF, Saf ve Edge "tüm tarayıcılar" değildir.
PKD

1

Bu benim için çalıştı

<select ng-init="basicProfile.casteId" ng-model="basicProfile.casteId" class="form-control">
     <option value="0">Select Caste....</option>
     <option data-ng-repeat="option in formCastes" value="{{option.id}}">{{option.casteName}}</option>
 </select>

Sadece seçeneği listeye ekler ve boş alanı ne yazık ki bırakır.
AMontpetit

1

Bu mükemmel çalışıyor

<select ng-model="contact.Title" ng-options="co for co in['Mr.','Ms.','Mrs.','Dr.','Prof.']">
    <option style="display:none" value=""></option>
</select>

çalışma şekli, bunun bir şey seçmeden önce görüntülenecek ilk seçeneği vermesidir display:noneve açılır menüden kaldırır, böylece isterseniz

<select ng-model="contact.Title" ng-options="co for co in['Mr.','Ms.','Mrs.','Dr.','Prof.']">
    <option style="display:none" value="">select an option...</option>
</select>

ve bu select and optionseçmeden önce size verecektir, ancak bir kez seçildikten sonra kaybolacak ve açılır listede görünmeyecektir.


Aslında sorunun kendisine cevap vermiyorsunuz, bundan daha kötüsü, sadece unsuru saklıyorsunuz.
Marco

0

Bunu kontrol cihazınızda aynı sırayla deneyin:

$scope.typeOptions = [
    { name: 'Feature', value: 'feature' }, 
    { name: 'Bug', value: 'bug' }, 
    { name: 'Enhancement', value: 'enhancement' }
];
$scope.form.type = $scope.typeOptions[0];

Metodunu denedim ama maalesef işe yaramadı. Bu kemana bir bakabilir misin? jsfiddle.net/5PdaX
Aniket Sinha

0

İşte düzeltme:

gibi bir örnek veri için:

financeRef.pageCount = [{listCount:10,listName:modelStrings.COMMON_TEN_PAGE},    
{listCount:25,listName:modelStrings.COMMON_TWENTYFIVE_PAGE},
{listCount:50,listName:modelStrings.COMMON_FIFTY_PAGE}];

Seçim seçeneği şu şekilde olmalıdır: -

<select ng-model="financeRef.financeLimit" ng-change="financeRef.updateRecords(1)" 
class="perPageCount" ng-show="financeRef.showTable" ng-init="financeRef.financeLimit=10"
ng-options="value.listCount as value.listName for  value in financeRef.pageCount"
></select>

Biz yazarken varlık noktası value.listCountolarak value.listName, otomatik metin doldurur value.listNameancak seçili seçeneğinin değeridirvalue.listCount değerleri 0,1,2, normal .. vb göstermek Gözat rağmen !!!

Benim durumumda, financeRef.financeLimitaslında kapma value.listCountve kontrolörde manipülasyonumu dinamik olarak yapabilirim.


0

Başlangıç ​​değeri bazı üst öğeden veya 1.5 bileşeninden bir bağlanma geliyorsa, uygun türün geçtiğinden emin olun. Kullanıyorsanız@ , iletilen değişken dize olur ve seçenekler ör. tamsayıların ardından boş seçenek görünecektir.

Her iki ayrıştırma doğru init değer ya da bağlanma <olup @(daha az gerekli olmadıkça performansı için tavsiye edilir).


0

Basit çözüm

<select ng-model='form.type' required><options>
<option ng-repeat="tp in typeOptions" ng-selected="    
{{form.type==tp.value?true:false}}" value="{{tp.value}}">{{tp.name}}</option>


0

Seçeneklerin kontrolü elinizde olmadığında jQuery ile öğütme çözümü

html:

<select id="selector" ng-select="selector" data-ng-init=init() >
...
</select>

js:

$scope.init = function () {
    jQuery('#selector option:first').remove();
    $scope.selector=jQuery('#selector option:first').val();
}

Pascal, birisi sizi reddetti çünkü bu AngularJs değil, jQuery çözümü
Mawg, Monica

Soru, Angular'ın daha fazlasını kazmak için soruluyor ...: - /
Sahu V Kumar

0

Bu sorunu çözmek için modelinizi ng-init kullanıyorsanız:

<select ng-model="foo" ng-app ng-init="foo='2'">

0

aynı sorunu vardı, ben ("ng-model" kaldırıldı) bu değişti:

<select ng-model="mapayear" id="mapayear" name="mapayear" style="  display:inline-block !important;  max-width: 20%;" class="form-control">
  <option id="removable" hidden> Selecione u </option>
    <option selected ng-repeat="x in anos" value="{{ x.ano }}">{{ x.ano }}
</option>
</select>

buna:

<select id="mapayear" name="mapayear" style="  display:inline-block !important;  max-width: 20%;" class="form-control">
  <option id="removable" hidden> Selecione u </option>
    <option selected ng-repeat="x in anos" value="{{ x.ano }}">{{ x.ano }}
</option>
</select>

şimdi çalışıyor, ama benim durumumda bu kapsamı ng.controller'dan sildiğimden dolayı, aynı şeyi yapmadım mı kontrol edin.



0

Benim için çalıştı tek şey kullanıyor track byyılında ng-optionsbu gibi:

 <select class="dropdown" ng-model="selectedUserTable" ng-options="option.Id as option.Name for option in userTables track by option.Id">


Ben kullanıyorsanız bu ng-optionben set değerine istediğiniz dizinin son değeri elde optionarasında select.
Çözülmedi

0

Bu sorunların üstesinden gelmek için angularjs belgelerindeki örneğe bakın.

  1. Buradaki dokümantasyon bağlantısına gidin
  2. ' Seçimi ngModel ayrıştırma / biçimlendirme yoluyla dize olmayan bir değere bağlama '
  3. Orada u görebilirsiniz, ' convertToNumber ' adlı direktif sorunu çözmek.

Benim için çalışıyor. Burada nasıl çalıştığını da görebilir


0

İlk seçeneği gizlemek için CSS kullanabiliriz, ancak IE 10, 11'de çalışmaz. En iyi yol, Jquery kullanarak öğeyi kaldırmaktır. Bu çözüm, krom ve IE10, 11'de test edilen büyük tarayıcı için çalışır

Ayrıca açısal kullanıyorsanız, bazen setTimeout kullanarak çalışır

$scope.RemoveFirstOptionElement = function (element) {
    setTimeout(function () {
        $(element.children()[0]).remove();
    }, 0);
};
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.