AngularJSとng-repeatを使用したselectの初期化


133

AngularJS 1.1.5でng-repeatを使用して、事前に入力されたオプションで選択ボックスを開始しようとしています。その代わり、選択は常に何も選択されていない状態から始まります。空のオプションもありますが、これは必要ありません。何も選択されていないという副作用があると思います。

ng-repeatの代わりにng-optionsを使用してこれを機能させることができますが、この場合はng-repeatを使用したいと思います。絞り込んだ例では表示していませんが、各オプションのtitle属性も設定したいので、ng-optionsを使用してこれを行う方法はありません。

これは一般的なAngularJのスコープ/プロトタイプ継承の問題に関連しているとは思いません。少なくとも私はバタランで調べたときに何も明白なものを見ていません。さらに、UIの選択でオプションを選択すると、モデルは正しく更新されます。

HTMLは次のとおりです。

<body ng-app ng-controller="AppCtrl">
    <div>
        Operator is: {{filterCondition.operator}}
    </div>
    <select ng-model="filterCondition.operator">
       <option 
           ng-repeat="operator in operators" 
           value="{{operator.value}}"
       >
           {{operator.displayName}}
       </option>
    </select>
</body>

そしてJavaScript:

function AppCtrl($scope) {

    $scope.filterCondition={
        operator: 'eq'
    }

    $scope.operators = [
        {value: 'eq', displayName: 'equals'},
        {value: 'neq', displayName: 'not equal'}
     ]
}

JS Fiddle for this:http : //jsfiddle.net/coverbeck/FxM3B/2/


1
ngRepeatでこれを行うクリーンな方法がなかったため、ngOptionが作成されました。ngRepeatは、オプションが選択された後に展開します。オプションにngSelectを設定してみましたか
TheSharpieOne

はい!ngSelectedが機能しました!更新された動作するJsFiddleを投稿します。
Charles O.

AngualrJS 1.2では、このコードの動作が異なります。新しい空の<OPTION>要素は作成されませんが、リストボックスの最初のオプションしか選択できません。あなたはそれをここで
VitalyB

回答:


226

OK。正しい方法を使用したくない場合は、ディレクティブの条件チェックロジックで属性をng-options追加して、事前選択を機能させることができます。ng-selectedoption

<select ng-model="filterCondition.operator">
    <option ng-selected="{{operator.value == filterCondition.operator}}"
            ng-repeat="operator in operators"
            value="{{operator.value}}">
      {{operator.displayName}}
    </option>
</select>

Working Demo


37
あなたが自分でそれを理解し、完全な例を実行したので、私はあなたに信用を与えます。ng-optionsが「正しい方法」であるというあなたのコメントには同意しませんが。:)私は常に自分でng-optionsを使用してきましたが、これにはng-optionsがサポートしていない、小さなものを実行する必要がありました。また、Angularのドキュメントには、ng-repeatも使用できると書かれています。おかげで、チャールズ
チャールズO.

おかげで、これはいくつかのオプションを無効にする簡単な方法でした。
ドリアン

11
ng-optionsは、そのユースケースが適切な場合にのみ正しいです。あなたは、などのオプション/ OPTGROUPフィールドに追加の属性/クラスが必要な場合があります
mystrdat

6
「正しい方法」が機能しないことがある(たとえば、オプション名を入力する文字列を翻訳したい場合)
btk

11
ng-selected式には{{}}がないことが必要だと思います:ng-selected = "operator.value == filterCondition.operator"
mvermand 2015年

35

selectタグの場合、angularはng-optionsディレクティブを提供します。これは、オプションを設定してデフォルトを設定するための特定のフレームワークを提供します。期待どおりに機能するng-optionsを使用した更新済みのフィドルは次のとおりです。http//jsfiddle.net/FxM3B/4/

更新されたHTML(コードは同じまま)

<body ng-app ng-controller="AppCtrl">
<div>Operator is: {{filterCondition.operator}}</div>
<select ng-model="filterCondition.operator" ng-options="operator.value as operator.displayName for operator in operators">
</select>
</body>

3
こんにちはジェレミー-私はng-optionsなしでこれをやろうとしています。私の質問とショーンへの返信で述べたように、各オプションにタイトル属性を設定したいのですが、ng-optionsでそれを行うことはできません。ありがとう、チャールズ
チャールズO.

9

ng-selectedオプションを指摘してくれたTheSharpieOneに感謝します。それがコメントではなく回答として投稿されていたとしたら、私はそれを正しい答えにしたでしょう。

これが動作しているJSFiddleです:http ://jsfiddle.net/coverbeck/FxM3B/5/ 。

また、問題の原因ではなかったので、元の投稿で省略していたtitle属性を使用するようにフィドルを更新しました(ただし、これがng-optionsではなくng-repeatを使用する理由です)。 。

HTML:

<body ng-app ng-controller="AppCtrl">
<div>Operator is: {{filterCondition.operator}}</div>
<select ng-model="filterCondition.operator">
   <option ng-repeat="operator in operators" title="{{operator.title}}" ng-selected="{{operator.value == filterCondition.operator}}" value="{{operator.value}}">{{operator.displayName}}</option>
</select>
</body>

JS:

function AppCtrl($scope) {

    $scope.filterCondition={
        operator: 'eq'
    }

    $scope.operators = [
        {value: 'eq', displayName: 'equals', title: 'The equals operator does blah, blah'},
        {value: 'neq', displayName: 'not equal', title: 'The not equals operator does yada yada'}
     ]
}

コメントとして投稿して申し訳ありません。私は例を作る気がなく、それがうまくいくかどうか100%確信していませんでした。それはただの予感でした。
TheSharpieOne 2013

9

angularが空のオプション要素をselectに注入しているという事実は、デフォルトでそれにバインドされたモデルオブジェクトが初期化されたときに空の値を伴うということです。

デフォルトのオプションを選択する場合は、コントローラーのスコープに設定できます。

$scope.filterCondition.operator = "your value here";

空のオプションプレースホルダーにしたい場合、これは私にとってはうまくいきます

<select ng-model="filterCondition.operator" ng-options="operator.id as operator.name for operator in operators">
  <option value="">Choose Operator</option>
</select>

2
これは良いですが、Angularは空白のオプションを作成します。これを回避するには?
MarceloBarbosa

1

提案されているように、ng-optionsを使用する必要があります。残念ながら、配列の要素をデフォルトで参照する必要があります(配列が文字列の配列である場合を除く)。

http://jsfiddle.net/FxM3B/3/

JavaScript:

function AppCtrl($scope) {


    $scope.operators = [
        {value: 'eq', displayName: 'equals'},
        {value: 'neq', displayName: 'not equal'}
     ]

    $scope.filterCondition={
        operator: $scope.operators[0]
    }
}

HTML:

<body ng-app ng-controller="AppCtrl">
<div>Operator is: {{filterCondition.operator.value}}</div>
<select ng-model="filterCondition.operator" ng-options="operator.displayName for operator in operators">
</select>
</body>

理由はわかりますか、それともよろしいですか?ドキュメント(docs.angularjs.org/api/ng.directive:select)には、文字列以外の値にバインドする場合にのみng-optionsを使用する必要があると記載されています。私が言ったように私はtitle属性を使いたいのですが、ng-optionsでそれを行う方法はありません。<option title = "この選択の非常に長い説明" ...>のようなものありがとうございます。
Charles O.

ドキュメントのメモは少し不明瞭で、実際にはモデルに文字列を使用し、オプションに文字列の配列を用意する必要があることを意味します。「title」属性を使用する理由が気にならない場合、W3C w3schools.com/tags/tag_option.aspには表示されず、実際に使用したことを思い出せません。オブジェクトに説明を格納するだけで、モデルがバインドされているデータを取得できませんか?
ショーンサイン2013

リンクしたW3Cページで[グローバル属性]リンクをクリックすると、title属性がoption要素でサポートされていることがわかります。「ツールチップ」テキストを表示するためだけにtitle属性を使用しているため、オプションにカーソルを合わせると、そのオプションの意味をより詳しく説明できます。それは小さなことですが、できれば持っておくといいでしょう。
Charles O.

@CharlesO。私はあなたと同じようにしたいです。オブジェクト(文字列以外の値)を設定しますが、オプションリストでもタイトルを使用します。これに対する解決策はありますか?見つからないようです...
Wilt

1

md-selectとng-repeat md-optionを角度マテリアルから使用している場合ng-model-options="{trackBy: '$value.id'}"このペンに表示されているmd-selectタグにashを追加できます

コード:

<md-select ng-model="user" style="min-width: 200px;" ng-model-options="{trackBy: '$value.id'}">
  <md-select-label>{{ user ? user.name : 'Assign to user' }}</md-select-label>
  <md-option ng-value="user" ng-repeat="user in users">{{user.name}}</md-option>
</md-select>

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.