AngularJSのselectに空のオプションが含まれているのはなぜですか?


652

私は過去数週間、AngularJSを使用してきましたが、本当に気になるのは、http://docs.angularjs.org/api/ngの仕様で定義されているすべての順列または構成を試した後でもです。.directive:selectでも、select要素の最初の子として空のオプションを取得します。

これがジェイドです:

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

ここでコントローラ:

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

最後に、生成されるHTMLは次のとおりです。

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

それを取り除くために何をする必要がありますか?

PS:これはなくても機能しますが、複数選択なしでselect2を使用すると奇妙に見えます。

回答:


646

に渡されるオプションのセットにoptionによって参照される値ng-modelが存在しない場合、空が生成されますng-optionsます。これは、偶発的なモデルの選択を防ぐために起こります。AngularJSは、初期モデルが未定義であるか、オプションセットに含まれていないことを確認でき、モデル値を独自に決定したくない場合があります。

空のオプションを取り除きたい場合は、コントローラーの初期値を選択するだけです。

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

ここにjsFiddleがあります: http

つまり、空のオプションは、有効なモデルが選択されていないことを意味します(つまり、有効なモデルとは、オプションのセットから)。この空のオプションを取り除くには、有効なモデル値を選択する必要があります。


7
$ scope.form.type = '';の両方を試しました。そして$ scope.form.type = $ scope.typeOptions [0]、しかし私はまだこれをse-<option value = "?" selected = "selected"> </ option>
Sudhanshu 2012

5
このデータをJSに保存しても意味がない場合があります。その選択の内容を決定したのがサーバーである場合、JSがそれを複製する必要があるのはなぜですか?
heneryville 2013

11
配列を使用していて、null値の1つである場合、残念ながらこれは機能しません。
vpiTriumph 2013

6
空の中にテキストを追加することは可能ですか?<option>tat angularは次のようなものを生成しました<option value="?">Select an option</option>
RPDeshaies

3
@ Tareck117 <option value="">Select an option</option>は、オプションリストのnull値です。?文字は必要ありません。
セバスチャン

235

初期値が必要な場合は、@ pkozlowski.opensourceの回答を参照してください。これは、ng-initを使用して(コントローラーではなく)ビューに実装することもできます。

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

初期値が不要な場合は、「値が空の文字列に設定された単一のハードコードされた要素を要素にネストできます。この要素は、nullまたは「選択されていない」オプションを表します」:

<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、作業フィドル:jsfiddle.net/4qKyx/1 「タイプを選択」が表示されますが、それに関連付けられた値がないことに注意してください。そして、何か他のものを選択すると、それは二度と表示されません。(Chromeでテスト)
Mark Rajcok 2013年

1
@MarkRajcok-素晴らしい提案!トランスクルーディングディレクティブを使用した例を使用して、別の問題に遭遇しました。見て頂けますか?plnkr.co/edit/efaZdEQlNfoDihk1R1zc?p=preview
Jan-

2
この通報は、あなたがまだ見、キーボードで選択することができますですstackoverflow.com/a/8442831/57344ソリューション
HaveAGuess

2
参照-これは今のために働くかもしれないが、角度のドキュメントは、特にリピートngのほかに何のためNG-INITを使用しないことをお薦めしますdocs.angularjs.org/api/ng/directive/ngInit
エド・ノリス

3
IE10では機能しません。「タイプの選択」は常に表示され、選択可能です。
ロビン

121

角度<1.4

「null」をいずれかのオプションの有効な値として扱う人のために(「null」が以下の例のtypeOptionsの項目の1つの値であると想像してください)、自動的に追加されることを確認する最も簡単な方法を見つけましたオプションが非表示になっている場合は、ng-ifを使用します。

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

なぜng- hideではなくng-ifなのですか?上記の内側の最初のオプションをターゲットにするcssセレクターが必要なので、非表示のオプションではなく、「実際の」オプションをターゲットに選択します。e2eテストに分度器を使用していて、(何らかの理由で)by.css()を使用して選択オプションをターゲットにする場合に役立ちます。

角度> = 1.4

selectディレクティブとoptionsディレクティブのリファクタリングにより、using ng-ifは実行可能なオプションではなくなったため、ng-show="false"再度機能させるために頼る必要があります。


5
これは選択の正しい視覚的な動作であるため、受け入れられた答えである必要があります。あなたsize="5"はselects属性に入れて、何も選択されていないことがわかります!デフォルトの<select>要素のように!Angularがなぜmultiple属性なしのselectに対してそのようなことをしているのか理解できません...
Sebastian

1
はい、同意します。これは受け入れられる答えです。これが「角道」です。ng-ifは実際にdomからoptions要素を削除するため(falseの場合)、このソリューションは、「ハッキー」コーディングなしですべてのブラウザーで機能します(ng-hideまたはng-showとは異なります)。
Sander_P 2015年

2
@Sander_Pの定義では、このソリューションは私の見解では「ハッキー」なコーディングであると考えています(実際に何かを出して、角をだましてそれを取り出すようにしています)が、あなたは正しいと思います。「さらに良い」解決策は、価値のないフリッグセレクトを可能にすることです。一体何ですか?これはそうではなく、エッジシナリオです。
dudewad 2015

@dudewad:Angular 1.4でうまくいくかもしれません。1.4.0のAngularJSブログから:「ngOptionsは完全にリファクタリングされ、いくつかの迷惑なバグを修正できるようになりました」
Sander_P '27 / 07/27

1
ハハ「迷惑なバグ」。はい。さて、納品の3日前のアップグレードに関してはまだ少し気まぐれなので、今のところ、問題なく動いているように見えるソリューションを維持します。ただし、将来については注意してください:)ありがとう!
dudewad 2015

36

多分誰かのために役立つ:

ng-optionsの代わりにプレーンオプションを使用したい場合は、以下のようにすることができます:

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

モデルをインラインで設定します。ng-initを使用して空のオプションを取り除く


JSON配列ではなくOBJECTSを使用してng-optionsを設定する明確な例を見つけることができませんでした。2つを「変換」しようとすると、正しく出力されないだけでなく、「サイレント」に失敗します。私は自分が間違っていることの手がかりがありません。私はようやくオプションタグで単純なng-repeatを選択しました。私はそれがベストプラクティスではないことを知っていますが、少なくともそれはうまくいきます。誰かが私に詳細で簡単に入れ替え可能で、データオブジェクト(JSONではない)でng-optionsを使用したAngular-n00bフレンドリーなWORKINGの例を教えてくれれば、私は高揚するでしょう。ng-initも使用する場合は、2倍になります。
code-sushi

プレーンオプションを使用していますが、コントローラーでは、選択したドロップダウンの値を取得できないようです。例:alert($ scope.sortorder.value);を試しました。そして、alert($ scope.sortorder); どちらも未定義です。ここで選択した値を取得する方法は?
Maverick Riz、2015

本当にありがとうございました。私はコントローラに完全に役に立たないオブジェクトを書き込もうとしていましたが、単純な選択が必要でした。もう一度ありがとうございます。
ムハンマドビンユスラット2017年

22

同様のことが私にも起こっていて、angular 1.5へのアップグレードが原因でした。Angularの新しいバージョンでng-init解析しているようです。古いAngular では、値が「600」のオプションにマップされていましたが、Angular 1.5では、値が600のオプションが見つかると予想されているため、これは見つかりません。Angularはランダムな最初のアイテムを挿入します:ng-init="myModelName=600"<option value="600">First</option><option value=600>First</option>

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

角度<1.2.x

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

角度> 1.2

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

1
ありがとう!私の場合、ng-init(デフォルト値なし)を使用できないため、モデルを文字列にキャストし、それが機能しました!
ロドリゴグラサ

アプリケーションのプロダクションの問題に非常に役立ちます。ありがとう@Nabil Boag
Venki

3
これは確かに機能しますng-value="600"が、のoption代わりにを使用することをお勧めしvalueます。それは数値に解析し、今のように値を変換する必要はありません:)
最大

@Max私は多くの価値のある答えを試しましたが、あなたの答えが見つかるまでどれもうまくいきませんでした。ありがとうございました。
アンドリュー

21

ここにある多数の回答の中で、私にとっては有効な解決策を再投稿し、以下のすべての条件を満たしていると考えました。

  • 提供した ng-modelが偽である場合にプレースホルダー/プロンプトを(たとえば、「-select region-」w。value=""
  • ng-modelの値が偽である場合おり、ユーザーがオプションのドロップダウンを開くと、プレースホルダーが選択されます(ここに記載されている他の解決策により、最初のオプションが選択されて表示され、誤解を招く可能性があります)。
  • ユーザーが有効な値を選択解除できるようにし、基本的には偽の /デフォルト値を再度選択する

ここに画像の説明を入力してください

コード

<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

元のQ&A- https://stackoverflow.com/a/32880941/1121919


デフォルトが<option ng-selected="true" value="null">
ジュソピ2017年

つまり、ng-modelの値がnullとして設定されている場合、selectで角度が作成され、空のオプションになります
Flezcano

16

簡単な解決策:

select option:empty { display:none }

それが誰かを助けることを願っています。理想的には、選択された回答がアプローチである必要がありますが、それが不可能な場合は、パッチとして機能するはずです。


2
私のテストでは、これはChrome(新しいChrome、さらにはFirefox)とFirefoxでのみ機能します。IEとSafariが壊れています。オペラやその他のエッジブラウザについては知らない。いずれにせよ、残念ながらこれは良い解決策ではありません
dudewad 2015

<select>を閉じる前のhtmlまたはjsのどこに配置しますか
H Varma

1
@HVarma CSSルールです。スタイルシートまたは<style>タグ内に配置します
KK

@KKのstackoverflow.com/questions/48355599/...は、あなたはこれをチェックしてくださいすることはできますか?
Sudarshan Kalebere

14

はいng-modelプロパティが未定義の場合、ng-modelは空のオプション値を作成します。オブジェクトをng-modelに割り当てると、これを回避できます

角度コーディング

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

重要な注意点:

$ scope.collections [0]や$ scope.collections [1]のような配列のオブジェクトをng-modelに割り当てます。オブジェクトプロパティは使用しないでください。サーバーから選択オプション値を取得している場合は、コールバック関数を使用して、オブジェクトをng-modelに割り当てます

Angularドキュメントからのメモ

注:ngModelは値ではなく参照で比較します。これは、オブジェクトの配列にバインドするときに重要です。例を見るhttp://jsfiddle.net/qWzTb/

何度も試しましたが、ようやく見つかりました。


8

@ pkozlowski.opensourceと@Markの答えはどちらも正しいですが、値に関係なく、常にリストの最初の項目を選択する、わずかに変更したバージョンを共有したいと思います。

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

4

私はAngular 1.4xを使用していて、この例を見つけたので、ng-initを使用してselectに初期値を設定しました。

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

3


私は同じ問題に直面しました。通常の投稿で角度のあるフォームを投稿する場合、角度ではオプションの値をこれまで使用していた方法で設定できないため、この問題に直面します。「form.type」の値を取得すると、適切な値が見つかります。フォームポストではなく、角度付きオブジェクトを自分でポストする必要があります。


3

簡単な解決策は、オプションに空白の値""を設定することです。これにより、未定義の余分なオプションがなくなります。


5
Doenstは@ 1.4.3で機能します。フォームに2つの空のオプションが追加されるだけです
デニーミューラー

3

わかりました。実際、答えは非常に簡単です。Angularによって認識されないオプションがある場合、それは鈍いものを含みます。あなたが間違っているのは、ng-optionsを使用すると、オブジェクトを読み取る、[{ id: 10, name: test }, { id: 11, name: test2 }] right?

これは、モデル値が等しいと評価するために必要なものです。たとえば、選択した値を10にしたい場合、モデルを{ id: 10, name: test }10を選択するような値に設定する必要があるため、ごみ箱は作成されません。

それがみんなが理解するのに役立つことを願っています、私は試してみました:)


2

この解決策は私にとってはうまくいきます:

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

オプション要素へのCSSの適用がすべてのブラウザーで機能するわけではないため、反対票が生じる可能性があります。
カフォソ

Chrome、FireFox、Safari、Edgeでテストしたところ、すべてが機能しています。
MMM

@MMM「すべてのブラウザ」にはIEが含まれます。多くのユーザーがまだIE 10と11に行き詰まっているため、反対投票が発生したのはそのためと思われます。Chrome、fF、Saf、およびEdgeは「すべてのブラウザー」ではありません。
PKD

1

これは私のために働いた

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

リストにオプションを追加して、空のスペースを残しておくだけです。
AMontpetit 2016

1

これは完璧に機能します

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

それが機能する方法は、これは何かを選択する前に表示される最初のオプションを与えdisplay:none、ドロップダウンからそれを削除するので、あなたが望むなら

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

これにより、select and option選択前に表示されますが、選択すると非表示になり、ドロップダウンに表示されません。


実際には、質問自体には答えませんが、最悪の場合、要素を非表示にするだけです。
Marco

0

これをコントローラで同じ順序で試してください:

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

私はあなたの方法を試しましたが、残念ながらそれを機能させることができませんでした。このフィドルを見てください。jsfiddle.net/5PdaX
Aniket Sinha

0

ここに修正があります:

次のようなサンプルデータの場合:

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

選択オプションは次のようになります:-

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

ポイントは、と書くvalue.listCountvalue.listName、テキストが自動的に入力value.listNameされますが、選択したオプションの値はvalue.listCount通常の0、1、2 ..と表示、以下です!!!

私の場合、financeRef.financeLimitは実際にを取得してvalue.listCountおり、コントローラで動的に操作できます。


0

追加したいのは、初期値が親要素または1.5コンポーネントからのバインディングからのものである場合は、適切なタイプが渡されていることを確認してください。@バインディングで使用する場合、渡される変数は文字列で、オプションがたとえば 整数の場合、空のオプションが表示されます。

initの値を適切に解析するか、バインディングを使用してバインディングを使用<しないでください@(必要な場合以外は、パフォーマンスを低下させるため推奨されません)。


0

シンプルなソリューション

<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

オプションを制御できない場合のjQueryによるグラインドソリューション

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、これはAngularJsではなくjQueryソリューションであるため、誰かがあなたに反対票を投じました
Mawgはモニカを18:17

Angularの詳細を掘り下げるように質問されます...:-/
Sahu V Kumar


0

私は同じ問題を抱えていました、私は(「ng-model」を削除して)これを変更しました:

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

これに:

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

現在は機能していますが、私の場合はng.controllerからスコープを削除したため、同じことを行っていないかどうかを確認してください。



0

私のために働いた唯一のものは、このようにで使用track byするng-optionsことです:

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


私はこれを使用している場合ng-option、私は一連の値にしたい配列の最後の値を取得optionのをselect。それは解決しませんでした:(
rufatZZ

0

これらの問題を克服する方法については、angularjsのドキュメントの例を参照してください。

  1. このドキュメントへのリンクはこちら
  2. ngModelの解析/フォーマットにより、文字列以外の値にバインド選択を検索 '
  3. そこで見ることができる、 ' convertToNumber ' と呼ばれるディレクティブが問題を解決します。

わたしにはできる。ここでどのように機能するかも確認できます


0

CSSを使用して最初のオプションを非表示にすることができますが、IE 10、11では機能しません。最善の方法は、Jqueryを使用して要素を削除することです。このソリューションは、ChromeとIE10、11でテストされた主要なブラウザで機能します

また、angularを使用している場合は、setTimeoutを使用するとうまくいくことがあります

$scope.RemoveFirstOptionElement = function (element) {
    setTimeout(function () {
        $(element.children()[0]).remove();
    }, 0);
};
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.