web-dev-qa-db-ja.com

AngularJSのng-optionsを使用してselectを操作する

私は他の記事でそれについて読んだことがありますが、私はそれを理解することができませんでした。

私は配列を持っています

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

私はそれを次のようにレンダリングしたいです。

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

また、ID = 000002のオプションを選択します。

selectを読んでみましたが、わかりません。

428
Andrej Kaurin

私はAngularJSを学んでいて、選択にも苦労していました。私はこの質問がすでに答えられていることを知っています、それでも私はもう少しコードを共有したいと思いました。

私のテストでは、私は2つのリストボックスを持っています:自動車メーカーと自動車モデル。モデルリストは、makeが選択されるまで無効になります。メイクリストボックスの選択が後でリセットされた場合( 'Select Make'に設定された場合)、モデルリストボックスは再び無効になり、選択もリセットされます( 'Select Model'に)モデルはハードコーディングされているのに対して、メークはリソースとして取得されます。

JSONになります:

[
{"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ファイル

<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"};
}
89
mp31415

何らかの理由でAngularJSは私を混乱させてしまいます。彼らのドキュメンテーションはこれでかなり恐ろしいです。バリエーションのより良い例は大歓迎です。

とにかく、私はBen Leshの答えに少しバリエーションがあります。

私のデータコレクションは次のようになります。

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

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

それでもoptionsの値はインデックス(0、1、2など)になります。

トラック追加 私のためにそれを修正しました:

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

選択リストにオブジェクトの配列を追加したいと思うことが多いと思いますので、これを覚えておきます。

AngularJS 1.4からはこれ以上ng-optionsを使用できなくなりましたが、オプションタグにng-repeatを使用する必要があります。

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

質問はすでに回答されています(ところで、Benによって提供された本当に良い包括的な回答)が、完全性のために別の要素を追加したいと思います。

ベンによって示唆された例では:

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

次の ngOptions 形式が使用されています:select as label for value in array

ラベル は式であり、その結果は<option>要素のラベルになります。その場合、より複雑なオプションラベルを付けるために、特定の文字列連結を実行できます。

例:

  • ng-options="item.ID as item.Title + ' - ' + item.ID for item in items"はあなたにTitle - IDのようなラベルを与えます
  • ng-options="item.ID as item.Title + ' (' + item.Title.length + ')' for item in items"Title (X)のようなラベルを与えます。ここでXはTitle文字列の長さです。

たとえば、フィルタを使うこともできます。

  • ng-options="item.ID as item.Title + ' (' + (item.Title | uppercase) + ')' for item in items"Title (TITLE)のようなラベルを与えます。ここでTitleプロパティのTitle値とTITLEは同じ値ですが大文字に変換されます。
  • モデルにプロパティSomeDateがある場合、ng-options="item.ID as item.Title + ' (' + (item.SomeDate | date) + ')' for item in items"Title (27 Sep 2015)のようなラベルを与えます。
15
Tom

CoffeeScriptの場合:

#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>
7
Akatsuki Sai

各オプションにカスタムタイトルが必要な場合は、ng-optionsは適用されません。代わりにng-repeatをオプション付きで使用してください。

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

私は以下があなたのために働くことを願っています。

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

それは役に立つかもしれません。結合は常に機能するわけではありません。

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

たとえば、RESTサービスからオプションリストのソースモデルを入力します。選択された値はリストを埋める前にわかっていて、設定されていました。 $ httpでRESTリクエストを実行した後、リストオプションは完了です。

しかし選択されたオプションは設定されていません。未知の理由でshadow $ digestを実行中のAngularJSは本来あるべき状態でバインド選択されていません。私はjQueryを使って選択を設定する必要があります。それは重要です! AngularJSは、影付きで、ng-repeatオプションで生成されたattrの "value"の値に接頭辞を追加します。 intの場合は "number:"です。

$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);
           }
       });
}
1
trueboroda