web-dev-qa-db-ja.com

AngularJSのng-optionsにvalueプロパティを設定するにはどうすればよいですか?

これが、私を含む多くの人々を悩ませているようです。

AngularJSでng-optionsディレクティブを使用して<select>タグのオプションを入力するときに、オプションの値を設定する方法がわかりません。これに関するドキュメントは本当に不明瞭です - 少なくとも私のような単純な人のために。

オプションのテキストを簡単に設定できます。

ng-options="select p.text for p in resultOptions"

resultOptionsが例えば

[
    {
        "value": 1,
        "text": "1st"
    },
    {
        "value": 2,
        "text": "2nd"
    }
]

オプションの値を設定するのが最も簡単な方法であるはずです(そしておそらくそうです)、今のところ私はそれを得ません。

542
Jukka Puranen

ngOptionsを参照してください。

ngOptions(オプション) - {comprehension_expression=} - 次のいずれかの形式になります。

配列データソースの場合label for value in arrayselect as label for value in arraylabel group by group for value in arrayselect as label group by group for value in array track by trackexprオブジェクトデータソースの場合:label for (key , value) in objectselect as label for (key , value) in objectlabel group by group for (key, value) in objectselect as label group by group for (key, value) in object

あなたの場合は、

array = [{ "value": 1, "text": "1st" }, { "value": 2, "text": "2nd" }];

<select ng-options="obj.value as obj.text for obj in array"></select>

更新

AngularJSの更新により、value要素のselect属性の実際の値をtrack by式で設定できるようになりました。

<select ng-options="obj.text for obj in array track by obj.value">
</select>

この醜いものを覚える方法

この構文形式を覚えるのに苦労しているすべての人々に:私はこれが最も簡単で美しい構文ではないことに同意します。この構文はPythonのリスト内包表記の拡張版の一種であり、それを知っていると構文を覚えやすくなります。それはこのようなものです:

Pythonコード:

my_list = [x**2 for x in [1, 2, 3, 4, 5]]
> [1, 4, 9, 16, 25]

# Let people to be a list of person instances
my_list2 = [person.name for person in people]
> my_list2 = ['Alice', 'Bob']

これは実際には上記の最初のものと同じ構文です。しかし、<select>では、通常、コード内の実際の値と<select>要素に表示されるテキスト(ラベル)を区別する必要があります。

同様に、コードにperson.idが必要ですが、idをユーザーに見せたくありません。その名前を見せたいのです。同様に、コード内のperson.nameには関心がありません。ラベルを付けるためのasキーワードがあります。だからそれはこのようになります:

person.id as person.name for person in people

あるいは、person.idの代わりにperson instance/referenceそのものが必要になるかもしれません。下記参照:

person as person.name for person in people

JavaScriptオブジェクトにも同じ方法が適用されます。オブジェクト内のアイテムは(key, value)ペアで分解されていることを忘れないでください。

680
Umur Kontacı

値属性がその値を取得する方法

  • データソースとして配列を使用する場合、それは各反復における配列要素のインデックスになります。
  • データソースとしてオブジェクトを使用する場合、それは各反復でプロパティ名になります。

だからあなたの場合はそれがなければなりません:

obj = { '1': '1st', '2': '2nd' };

<select ng-options="k as v for (k,v) in obj"></select>
133
frm.adiputra

私もこの問題を抱えていました。 ng-optionsに値を設定できませんでした。生成されたすべてのオプションは、0、1、...、nで設定されています。

それを正しくするために、私はng-optionsで次のようなことをしました。

HTML:

<select ng-options="room.name for room in Rooms track by room.price">
    <option value="">--Rooms--</option>
</select>

私はすべての値をroom.priceで設定するために "track by"を使います。

(この例では、複数の価格が同じであるとコードが失敗する可能性があります。異なる値を使用するようにしてください。)

JSON:

$scope.Rooms = [
            { name: 'SALA01', price: 100 },
            { name: 'SALA02', price: 200 },
            { name: 'SALA03', price: 300 }
        ];

ブログ記事から学びましたAngular.JS ng-options&trackを使ってselect要素の初期選択値を設定する方法

ビデオを見る。それはいいクラスです:)

118
Bruno Gomes

フォームが最終的にサーバーに送信されるためにoption要素の値を変更したい場合は、これを行うのではなく、

<select name="text" ng-model="text" ng-options="select p.text for p in resultOptions"></select>

あなたはこれを行うことができます:

<select ng-model="text" ng-options="select p.text for p in resultOptions"></select>
<input type="hidden" name="text" value="{{ text }}" />

期待値は、正しい名前でフォームを介して送信されます。

46
neemzy

通常のフォーム送信を使用してmy_heroというカスタム値をサーバーに送信するには、次のようにします。

JSON:

"heroes": [
  {"id":"iron", "label":"Iron Man Rocks!"},
  {"id":"super", "label":"Superman Rocks!"}
]

HTML:

<select ng-model="hero" ng-options="obj.id as obj.label for obj in heroes"></select>
<input type="hidden" name="my_hero" value="{{hero}}" />

サーバーはmy_heroの値としてironまたはsuperを受け取ります。

これは @neemzyによる答え と似ていますが、value属性に個別のデータを指定します。

25
Philip Bulley

ng-optionsは使用するのが複雑(おそらくイライラする)ようですが、実際にはアーキテクチャ上の問題があります。

AngularJSは、動的HTML + JavaScriptアプリケーションのMVCフレームワークとして機能します。その(V)iewコンポーネントはHTMLの「テンプレート」を提供していますが、その主な目的は、コントローラを介してユーザーのアクションをモデルの変更に結び付けることです。したがって AngularJSで機能するための適切な抽象レベルは、select要素がモデル内の値をクエリからの値に設定することです

  • クエリ行がユーザにどのように提示されるかは(V)の関心事であり、ng-optionsforキーワードを提供してoption要素の内容をすなわちp.text for p in resultOptionsにするかを決定します。
  • 選択された行がサーバーにどのように提示されるかは、(M)odelの関心事です。したがってng-optionsは、k as v for (k,v) in objectsのようにモデルに提供される値を指定するasキーワードを提供します。

これが問題となる正しい解決策は本質的にアーキテクチャ上のものであり、必要に応じて(M)odelがサーバ通信を実行するようにHTMLをリファクタリングすることを含みます (ユーザがフォームを送信する代わりに)。

MVC HTMLページが当面の問題のために不要な過剰エンジニアリングであるなら: そしてAngularJS(V)iewコンポーネントのHTML生成部分のみを使用してください。この場合、&lt;li /&gt;の下の&lt;ul /&gt;のような要素を生成するために使用されているのと同じパターンに従って、option要素にng-repeatを配置します。

<select name=“value”>
    <option ng-repeat=“value in Model.Values” value=“{{value.value}}”>
        {{value.text}}
    </option>
</select>

kludge として、select要素のname属性を隠し入力要素にいつでも移動できます。

<select ng-model=“selectedValue” ng-options=“value.text for value in Model.Values”>
</select>
<input type=“hidden” name=“value” value=“{{selectedValue}}” />
23
Joshcodes

あなたはこれを行うことができます:

<select ng-model="model">
    <option value="">Select</option>
    <option ng-repeat="obj in array" value="{{obj.id}}">{{obj.name}}</option>
</select>

- アップデート

いくつかの更新の後、 user frm.adiputra の解決策 がはるかに優れています。コード:

obj = { '1': '1st', '2': '2nd' };
<select ng-options="k as v for (k,v) in obj"></select>
19
Liko

私は今日この問題にしばらく苦労しています。私はAngularJSのドキュメント、この記事や他の記事、そしてそれらが導くいくつかのブログを読んでいます。彼ら全員が私がより細かい詳細を理解するのを助けました、しかし結局これはちょうど混乱を招くトピックのようです。 ng-optionsの多くの構文上のニュアンスが主な原因です。

最後に、私にとっては、それがより少なくなってきました。

次のように構成されたスコープを考えます。

        //Data used to populate the dropdown list
        $scope.list = [
           {"FirmnessID":1,"Description":"Soft","Value":1},         
           {"FirmnessID":2,"Description":"Medium-Soft","Value":2},
           {"FirmnessID":3,"Description":"Medium","Value":3}, 
           {"FirmnessID":4,"Description":"Firm","Value":4},     
           {"FirmnessID":5,"Description":"Very Firm","Value":5}];

        //A record or row of data that is to be save to our data store.
        //FirmnessID is a foreign key to the list specified above.
        $scope.rec = {
           "id": 1,
           "FirmnessID": 2
        };

望ましい結果を得るために必要なのはこれだけです。

        <select ng-model="rec.FirmnessID"
                ng-options="g.FirmnessID as g.Description for g in list">
            <option></option>
        </select>   

track byを使用していないことに注意してください。 track byを使用すると、選択されたアイテムは、会社ID自体ではなく、会社IDに一致するオブジェクトを常に返します。これは私の基準を満たしています。つまり、オブジェクトではなく数値を返すべきであり、生成される各オプションに対して新しいスコープを作成しないことでパフォーマンスの向上を図るためにng-optionsを使用することです。

また、最初の空白行が必要だったので、<option>要素に<select>を追加しました。

これが私の仕事を示している Plunkr です。

13

新しい「トラックバイ」機能を使用する代わりに、値をテキストと同じにしたい場合は、単純にこれを配列で実行できます。

<select ng-options="v as v for (k,v) in Array/Obj"></select>

値がObject/Arrayのキーになるため、配列の場合は0、1、2などになる標準的な構文との違いに注意してください。

<select ng-options"k as v for (k,v) in Array/Obj"></select>

v as vv as vになります。

私は、構文を見ているという常識に基づいてこれを発見しました。 (k、v)は、配列/オブジェクトをキーと値のペアに分割する実際のステートメントです。

'k as v'ステートメントでは、kが値になり、vがユーザーに表示されるテキストオプションになります。私は「トラックバイ」は面倒でやり過ぎだと思います。

10
KthProg

私によれば、これはすべてのシナリオに最適でした。

<select ng-model="mySelection.value">
   <option ng-repeat="r in myList" value="{{r.Id}}" ng-selected="mySelection.value == r.Id">{{r.Name}}
   </option>
</select>

モデルを使用してデータをバインドできます。オブジェクトに含まれる値とシナリオに基づくデフォルトの選択が得られます。

10
blue

これが私がこれを解決した方法です。値による選択を追跡し、選択した項目のプロパティをJavaScriptコードのモデルに設定しました。

Countries =
[
    {
        CountryId = 1, Code = 'USA', CountryName = 'United States of America'
    },
    {
       CountryId = 2, Code = 'CAN', CountryName = 'Canada'
    }
]
<select ng-model="vm.Enterprise.AdminCountry" ng-options="country.CountryName for country in vm.Countries track by country.CountryId">

vmは私のコントローラで、サービスから取得したコントローラ内の国は{CountryId =1, Code = 'USA', CountryName='United States of America'}です。

選択ドロップダウンから別の国を選択して[保存]をクリックしてページを投稿すると、正しい国の境界が表示されます。

8
Archna

ng-optionsディレクティブは、配列の<options>要素にvalue属性を設定しません。

limit.value as limit.text for limit in limitsを使用すると、次のようになります。

<option>のラベルをlimit.textに設定します
limit.value値を選択のng-modelに保存します

スタックオーバーフローの質問AngularJSのng-optionsが値をレンダリングしないを参照してください。

7
timestopper
<select ng-model="color" ng-options="(c.name+' '+c.shade) for c in colors"></select><br>
4

質問の1年後、これらのどれもが少なくとも私には実際の答えを与えたので、私はこの質問に対する答えを見つけなければなりませんでした。

オプションの選択方法を尋ねましたが、これらの2つのことはではなくとは誰も言っていません:

このようなオプションがある場合:

$scope.options = [
    { label: 'one', value: 1 },
    { label: 'two', value: 2 }
  ];

そして、次のようなデフォルトのオプションを設定しようとします:

$scope.incorrectlySelected = { label: 'two', value: 2 };

これはではなく動作しますが、次のようなオプションを選択しようとすると:

$scope.correctlySelected = $scope.options[1];

WORKになります。

これらの2つのオブジェクトのプロパティは同じですが、AngularJSはreferenceで比較するため、AngularJSはそれらを異なるものと見なしています。

フィドルをご覧ください http://jsfiddle.net/qWzTb/

3
Aleks

現時点でこれがoption要素のvalue属性を明示的に制御する唯一の方法のように思われるので、この質問に対する正しい答えは ユーザーfrm.adiputra によって提供された)です。

しかし、ここでは "select"はキーワードではないことを強調したいだけですが、それは式の単なるプレースホルダーです。 "select"式およびng-optionsディレクティブで使用できる他の式の定義については、以下のリストを参照してください。

質問に示されているとおりのselectの使用

ng-options='select p.text for p  in resultOptions'

本質的に間違っています。

式のリストに基づいて、オプションがオブジェクトの配列で指定されている場合は、 trackexpr を使用して値を指定できますが、グループ化でのみ使用されています。


Ng-optionsについてのAngularJSのドキュメントから:

  • 配列/オブジェクト :反復する配列/オブジェクトに評価される式。
  • value :反復中に配列内の各項目またはobjectの各プロパティ値を参照するローカル変数。
  • key :反復中にobject内のプロパティ名を参照するローカル変数。
  • label :この式の結果はelementのラベルになります。式は、おそらく値変数(たとえばvalue.propertyName)を参照します。
  • select :この式の結果は、親要素のモデルにバインドされます。指定しない場合、選択式はデフォルトでvalueになります。
  • group :この式の結果は、DOM要素を使用してオプションをグループ化するために使用されます。
  • trackexpr :オブジェクトの配列を扱うときに使用されます。この式の結果は、配列内のオブジェクトを識別するために使用されます。 trackexprは、おそらくvalue変数(例えば、value.propertyName)を参照します。
3
Majix

データソースの設定方法によっては、ng-optionsで項目を選択するのが少し面倒になる場合があります。

しばらくの間彼らと戦った後、私は私が使う最も一般的なデータソースでサンプルを作ることになった。あなたはそれをここで見つけることができます:

http://plnkr.co/edit/fGq2PM?p=preview

Ng-optionsを機能させるために、考慮すべき点がいくつかあります。

  1. 通常は、一方のソースからオプションを取得し、もう一方のソースから選択した値を取得します。例えば:
    • states :: ng-optionsのデータ
    • user.state ::選択したものに設定するオプション
  2. 1に基づくと、行うべき最も簡単な/論理的なことは、選択を1つのソースで満たしてから、コードを介して選択された値を設定することです。めったに混合データセットを取得したほうがよいでしょう。
  3. AngularJSでは、選択コントロールにkey | label以上のものを保持できます。多くのオンラインの例では、オブジェクトを「キー」としています。オブジェクトからの情報が必要な場合はそのように設定します。それ以外の場合は、特定のプロパティをキーとして使用します。 (ID、CODEなど。plckrサンプルと同じ)
  4. ドロップダウン/選択コントロールの値を設定する方法は#3によって異なります。

    • ドロップダウンキーが単一のプロパティである場合(plunkrのすべての例のように)、それを設定するだけです。例:$scope.dropdownmodel = $scope.user.state;
    • オブジェクトをキーとして設定した場合、オプションをループ処理する必要があります。オブジェクトを割り当てても、項目が選択されたものに設定されることはありません。

      for (var i = 0, len = $scope.options.length; i < len; i++) {
        if ($scope.options[i].id == savedValue) { // Your own property here:
          console.log('Found target! ');
          $scope.value = $scope.options[i];
          break;
        }
      }
      

他のオブジェクト$scope.myObject.myPropertyの同じプロパティのsavedValueを置き換えることができます。

3
Itzco

私にとっては ブルーノ・ゴメスによる答え が最良の答えです。

しかし、実際には、選択オプションのvalueプロパティを設定することについて心配する必要はありません。 AngularJSがそれを引き受けます。詳しく説明させてください。

このフィドルを検討してください

angular.module('mySettings', []).controller('appSettingsCtrl', function ($scope) {

    $scope.timeFormatTemplates = [{
        label: "Seconds",
        value: 'ss'
    }, {
        label: "Minutes",
        value: 'mm'
    }, {
        label: "Hours",
        value: 'hh'
    }];


    $scope.inactivity_settings = {
        status: false,
        inactive_time: 60 * 5 * 3, // 15 min (default value), that is, 900 seconds
        //time_format: 'ss', // Second (default value)
        time_format: $scope.timeFormatTemplates[0], // Default seconds object
    };

    $scope.activity_settings = {
        status: false,
        active_time: 60 * 5 * 3, // 15 min (default value), that is,  900 seconds
        //time_format: 'ss', // Second (default value)
        time_format: $scope.timeFormatTemplates[0], // Default seconds object
    };

    $scope.changedTimeFormat = function (time_format) {
        'use strict';

        console.log('time changed');
        console.log(time_format);
        var newValue = time_format.value;

        // do your update settings stuffs
    }
});

フィドル出力に見られるように、選択ボックスのオプションに選択したものは何でも、それはあなたのカスタム値、またはAngularJSによる0、1、2の自動生成値です。その選択コンボボックスオプションの値にアクセスし、それに応じてそれを操作するための他のライブラリ。

3
Sanjay Khadka

選択ボックス内の値とラベルを区別するプロパティ別の追跡を使用してください。

してみてください

<select ng-options="obj.text for obj in array track by obj.value"></select>

これは(配列からの)テキスト付きのラベルと値付きの値を割り当てます。

3
Shashank Saxena

Ng-optionsを使用して、値および表示メンバーへの選択タグのバインドを実現できます。

このデータソースを使用している間

countries : [
              {
                 "key": 1,
                 "name": "UAE"
             },
              {
                  "key": 2,
                  "name": "India"
              },
              {
                  "key": 3,
                  "name": "OMAN"
              }
         ]

あなたはあなたのselectタグをvalueとnameに結び付けるために以下を使うことができます

<select name="text" ng-model="name" ng-options="c.key as c.name for c in countries"></select>

それは素晴らしい作品

3

オブジェクトの場合:

<select ng-model="mySelect" ng-options="key as value for (key, value) in object"></select>
2
EpokK

チュートリアルANGULAR.JS:NG-SELECTとNG-OPTIONSは私が問題を解決するのを助けました:

<select id="countryId"
  class="form-control"
  data-ng-model="entity.countryId"
  ng-options="value.dataValue as value.dataText group by value.group for value in countries"></select>
2
Ricardo Huertas

開発者がng-optionsを使用するのは常に面倒です。例:selectタグで空の/空白の選択値を取得する。特にng-optionsでJSONオブジェクトを扱うとき、それはもっと面倒になります。ここで私はそれについていくつかの演習をしました。

目的:ng-optionを使用してJSONオブジェクトの配列を繰り返し、選択した最初の要素を設定します。

データ:

someNames = [{"id":"1", "someName":"xyz"}, {"id":"2", "someName":"abc"}]

Selectタグでは、xyzとabcを表示する必要がありました。ここで、xyzはあまり手間をかけずに選択する必要があります。

HTML:

<pre class="default prettyprint prettyprinted" style=""><code>
    &lt;select class="form-control" name="test" style="width:160px"    ng-options="name.someName for name in someNames" ng-model="testModel.test" ng-selected = "testModel.test = testModel.test || someNames[0]"&gt;
&lt;/select&gt;
</code></pre>

上記のコード例では、この誇張から抜け出すことができます。

別の 参照

2
Sam Jha
<select ng-model="output">
   <option ng-repeat="(key,val) in dictionary" value="{{key}}">{{val}}</option>
</select>
1
ethanneff

コードスニペットを実行してバリエーションを確認してください。ここに素早い理解のためのメモがあります

  1. 例1(オブジェクト選択) - ng-option="os.name for os in osList track by os.id"。ここでtrack by os.idは重要です&thereとos.id asNOTos.nameの前に持ってください)。

    • ng-model="my_os"は、キーがidで、my_os={id: 2}のように)のオブジェクトに設定する必要があります。
  2. 例2(値の選択): - ng-option="os.id as os.name for os in osList"。ここではtrack by os.idNOTがあり、os.id asos.nameの前にがあるはずです).

    • ng-model="my_os"は、my_os= 2のような値に設定する必要があります。

残りのコードスニペットが説明します。

angular.module('app', []).controller('ctrl', function($scope, $timeout){
  
  //************ EXAMPLE 1 *******************
  $scope.osList =[
    { id: 1, name :'iOS'},
    { id: 2, name :'Android'},
    { id: 3, name :'Windows'}
  ]
  $scope.my_os = {id: 2};
  
  
  //************ EXAMPLE 2 *******************
  $timeout(function(){
    $scope.siteList = [
          { id: 1, name: 'Google'},
          { id: 2, name: 'Yahoo'},
          { id: 3, name: 'Bing'}
        ];
   }, 1000);
    
    $scope.my_site = 2;
  
    $timeout(function(){
      $scope.my_site = 3;
    }, 2000);
})
fieldset{
  margin-bottom: 40px;
  }
strong{
  color:red;
  }
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.10/angular.min.js"></script>

<div ng-app="app" ng-controller="ctrl">

  <!--//************ EXAMPLE 1 *******************-->
  <fieldset>
    <legend>Example 1 (Set selection as <strong>object</strong>)</legend>
    
    <select ng-model="my_os" ng-options="os.name for os in osList track by os.id">
        <option value="">--Select--</option>
      </select>
    {{my_os}}
    
  </fieldset>
  
  
  <!--//************ EXAMPLE 2 *******************-->
  <fieldset>
    <legend>Example 2 (Set selection as <strong>value</strong>. Simulate ajax)</legend>
      <select ng-model="my_site" ng-options="site.id as site.name for site in siteList">
        <option value="">--Select--</option>
      </select>
      {{my_site}}
  </fieldset>
  
</div>
1

ngOptionsディレクティブ

$scope.items = [{name: 'a', age: 20},{ name: 'b', age: 30},{ name: 'c', age: 40}];
  • 配列内の値のCase-1)ラベル:

    <div>
        <p>selected item is : {{selectedItem}}</p>
        <p> age of selected item is : {{selectedItem.age}} </p>
        <select ng-model="selectedItem" ng-options="item.name for item in items">
        </select>
    </div>
    

出力説明(最初の項目が選択されたとします):

selectedItem = {name: 'a'、age:20} // [デフォルトでは、選択された項目は item に等しい

selectedItem.age = 20

  • ケース-2)配列の値のラベルとして選択:

    <div>
        <p>selected item is : {{selectedItem}}</p>
        <select ng-model="selectedItem" ng-options="item.age as item.name for item in items">
        </select>
    </div>
    

出力説明(最初の項目が選択されたとします): selectedItem = 20 // [選択部分は item.age ]

0
Masud Shrabon

レガシーアプリケーションでこの問題を解決する方法は次のとおりです。

HTMLの場合:

ng-options="kitType.name for kitType in vm.kitTypes track by kitType.id" ng-model="vm.itemTypeId"

JavaScriptの場合:

vm.kitTypes = [
    {"id": "1", "name": "Virtual"},
    {"id": "2", "name": "Physical"},
    {"id": "3", "name": "Hybrid"}
];

...

vm.itemTypeId = vm.kitTypes.filter(function(value, index, array){
    return value.id === (vm.itemTypeId || 1);
})[0];

私のHTMLはオプションの値を正しく表示します。

0
techguy2000

多くの人が前に言ったように、私がこのようなデータを持っているならば:

countries : [
              {
                 "key": 1,
                 "name": "UAE"
             },
              {
                  "key": 2,
                  "name": "India"
              },
              {
                  "key": 3,
                  "name": "OMAN"
              }
         ]

私はそれを使用するでしょう:

<select
    ng-model="selectedCountry"
    ng-options="obj.name for obj  in countries">
</select>

あなたのコントローラでは、最初の空の項目を取り除くために初期値を設定する必要があります。

 $scope.selectedCountry = $scope.countries[0];

 // You need to watch changes to get selected value
 $scope.$watchCollection(function() {
   return $scope.selectedCountry
 }, function(newVal, oldVal) {
     if (newVal === oldVal) {
       console.log("nothing has changed " + $scope.selectedCountry)
     } 
     else {
       console.log('new value ' + $scope.selectedCountry)
     }
 }, true)
0
Anjum....