简体   繁体   English

使用AngularJS的ng-options使用select

[英]Working with select using AngularJS's ng-options

I have read about it in other posts, but I couldn't figure it out. 我在其他帖子中已经阅读过它,但我无法弄明白。

I have an array, 我有一个阵列,

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

I want to render it as: 我想将其渲染为:

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

And also I want to select the option with ID=000002. 而且我想选择ID = 000002的选项。

I have read select and tried, but I can't figure it out. 我已经阅读过选择并试过了,但我无法弄明白。

One thing to note is that ngModel is required for ngOptions to work... note the ng-model="blah" which is saying "set $scope.blah to the selected value". 需要注意的一点是ngOode 需要 ngModel才能工作...注意ng-model="blah" ,它说“将$ scope.blah设置为所选值”。

Try this: 试试这个:

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

Here's more from AngularJS's documentation (if you haven't seen it): 这里有更多来自AngularJS的文档(如果你还没有看到它):

for array data sources: 对于数组数据源:

  • label for value in array 数组中值的标签
  • select as label for value in array 选择作为数组中值的标签
  • label group by group for value in array = select as label group by group for value in array 对于array中的值,按组分组标签=按数组中的值选择为标签组

for object data sources: 对于对象数据源:

  • label for (key , value) in object 对象中的(键,值)标签
  • select as label for (key , value) in object 选择对象中的(键,值)标签
  • label group by group for (key, value) in object 对象中的(键,值)按组标记
  • select as label group by group for (key, value) in object 为对象中的(键,值)按组选择标签

For some clarification on option tag values in AngularJS: 有关AngularJS中选项标记值的一些说明:

When you use ng-options , the values of option tags written out by ng-options will always be the index of the array item the option tag relates to . 使用ng-optionsng-options 写出的选项标签的值将始终是选项标签所涉及的数组项的索引 This is because AngularJS actually allows you to select entire objects with select controls, and not just primitive types. 这是因为AngularJS实际上允许您使用选择控件选择整个对象,而不仅仅是基本类型。 For example: 例如:

app.controller('MainCtrl', function($scope) {
   $scope.items = [
     { id: 1, name: 'foo' },
     { id: 2, name: 'bar' },
     { id: 3, name: 'blah' }
   ];
});
<div ng-controller="MainCtrl">
   <select ng-model="selectedItem" ng-options="item as item.name for item in items"></select>
   <pre>{{selectedItem | json}}</pre>
</div>

The above will allow you to select an entire object into $scope.selectedItem directly. 以上将允许您直接在$scope.selectedItem选择整个对象。 The point is, with AngularJS, you don't need to worry about what's in your option tag. 关键是,使用AngularJS,您无需担心选项标签中的内容。 Let AngularJS handle that; 让AngularJS处理; you should only care about what's in your model in your scope. 你应该只关心你范围内模型中的内容。

Here is a plunker demonstrating the behavior above, and showing the HTML written out 这是一个展示上述行为的plunker,并显示HTML写出来


Dealing with the default option: 处理默认选项:

There are a few things I've failed to mention above relating to the default option. 我上面没有提到一些与默认选项有关的事情。

Selecting the first option and removing the empty option: 选择第一个选项并删除空选项:

You can do this by adding a simple ng-init that sets the model (from ng-model ) to the first element in the items your repeating in ng-options : 你可以通过添加一个简单的ng-init来设置模型(从ng-model )到你在ng-options重复的项目中的第一个元素:

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

Note: This could get a little crazy if foo happens to be initialized properly to something "falsy". 注意:如果foo恰好被初始化为“falsy”,这可能会有点疯狂。 In that case, you'll want to handle the initialization of foo in your controller, most likely. 在这种情况下,您最有可能想要在控制器中处理foo的初始化。

Customizing the default option: 自定义默认选项:

This is a little different; 这有点不同; here all you need to do is add an option tag as a child of your select, with an empty value attribute, then customize its inner text: 这里你需要做的就是添加一个选项标签作为你的选择的子项,使用空值属性,然后自定义其内部文本:

<select ng-model="foo" ng-options="item as item.name for item in items">
   <option value="">Nothing selected</option>
</select>

Note: In this case the "empty" option will stay there even after you select a different option. 注意:在这种情况下,即使您选择了其他选项,“空”选项也将保留在那里。 This isn't the case for the default behavior of selects under AngularJS. 对于AngularJS下的选择的默认行为,情况并非如此。

A customized default option that hides after a selection is made: 选择后隐藏的自定义默认选项:

If you wanted your customized default option to go away after you select a value, you can add an ng-hide attribute to your default option: 如果您希望在选择值后自定义默认选项消失,则可以将ng-hide属性添加到默认选项:

<select ng-model="foo" ng-options="item as item.name for item in items">
   <option value="" ng-if="foo">Select something to remove me.</option>
</select>

I'm learning AngularJS and was struggling with selection as well. 我正在学习AngularJS,并且也在努力选择。 I know this question is already answered, but I wanted to share some more code nevertheless. 我知道这个问题已经回答了,但我想分享更多的代码。

In my test I have two listboxes: car makes and car models. 在我的测试中,我有两个列表框:汽车制造和汽车模型。 The models list is disabled until some make is selected. 在选择某些make之前,模型列表将被禁用。 If selection in makes listbox is later reset (set to 'Select Make') then the models listbox becomes disabled again AND its selection is reset as well (to 'Select Model'). 如果稍后重置选择列表框(设置为'选择生成'),则模型列表框将再次被禁用并且其选择也将被重置(到“选择模型”)。 Makes are retrieved as a resource while models are just hard-coded. 将模型作为资源检索,而模型只是硬编码。

Makes JSON: 制作JSON:

[
{"code": "0", "name": "Select Make"},
{"code": "1", "name": "Acura"},
{"code": "2", "name": "Audi"}
]

services.js: services.js:

angular.module('makeServices', ['ngResource']).
factory('Make', function($resource){
    return $resource('makes.json', {}, {
        query: {method:'GET', isArray:true}
    });
});

HTML file: 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: 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"};
}

For some reason AngularJS allows to get me confused. 出于某种原因,AngularJS让我感到困惑。 Their documentation is pretty horrible on this. 他们的文件非常可怕。 More good examples of variations would be welcome. 我们欢迎更多有关变化的好例子。

Anyway, I have a slight variation on Ben Lesh's answer. 无论如何,我对Ben Lesh的答案略有不同。

My data collections looks like this: 我的数据集如下所示:

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

Now 现在

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

still resulted in the options value to be the index (0, 1, 2, etc.). 仍然导致选项值成为索引(0,1,2等)。

Adding Track By fixed it for me: 添加曲目通过修复它为我:

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

I reckon it happens more often that you want to add an array of objects into an select list, so I am going to remember this one! 我想更常见的是你想要将一个对象数组添加到选择列表中,所以我要记住这一个!

Be aware that from AngularJS 1.4 you can't use ng-options any more, but you need to use ng-repeat on your option tag: 请注意,从AngularJS 1.4开始,您不能再使用ng-options,但需要在选项标签上使用ng-repeat

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

The question is already answered (BTW, really good and comprehensive answer provided by Ben), but I would like to add another element for completeness, which may be also very handy. 这个问题已经回答了(顺便提一下,Ben提供了非常好的和全面的答案),但我想补充一点完整性,这也可能非常方便。

In the example suggested by Ben: 在本建议的例子中:

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

the following ngOptions form has been used: select as label for value in array . 使用了以下ngOptions表单: select as label for value in array

Label is an expression, which result will be the label for <option> element. Label是一个表达式,其结果将是<option>元素的标签。 In that case you can perform certain string concatenations, in order to have more complex option labels. 在这种情况下,您可以执行某些字符串连接,以便拥有更复杂的选项标签。

Examples: 例子:

  • ng-options="item.ID as item.Title + ' - ' + item.ID for item in items" gives you labels like Title - ID 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" gives you labels like Title (X) , where X is length of Title string. ng-options="item.ID as item.Title + ' (' + item.Title.length + ')' for item in items"为您提供Title (X)等标签,其中X是Title string的长度。

You can also use filters, for example, 您也可以使用过滤器,例如

  • ng-options="item.ID as item.Title + ' (' + (item.Title | uppercase) + ')' for item in items" gives you labels like Title (TITLE) , where Title value of Title property and TITLE is the same value but converted to uppercase characters. ng-options="item.ID as item.Title + ' (' + (item.Title | uppercase) + ')' for item in items"为您提供Title (TITLE)等标签,其中Title属性的Title值和TITLE是相同的值,但转换为大写字符。
  • ng-options="item.ID as item.Title + ' (' + (item.SomeDate | date) + ')' for item in items" gives you labels like Title (27 Sep 2015) , if your model has a property SomeDate ng-options="item.ID as item.Title + ' (' + (item.SomeDate | date) + ')' for item in items"为您提供Title (27 Sep 2015)等标签,如果您的模型有属性SomeDate

In CoffeeScript: 在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>

If you need a custom title for each option, ng-options is not applicable. 如果您需要每个选项的自定义标题,则ng-options不适用。 Instead use ng-repeat with 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>

I hope the following will work for you. 我希望以下内容对您有用。

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

It can be useful. 它可能很有用。 Bindings do not always work. 绑定并不总是有效。

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

For example, you fill the options list source model from a REST service. 例如,您从REST服务填充选项列表源模型。 A selected value was known before filling the list, and it was set. 在填充列表之前已知选定的值,并且已设置。 After executing the REST request with $http, the list option is done. 使用$ http执行REST请求后,列表选项完成。

But the selected option is not set. 但是未设置所选选项。 For unknown reasons AngularJS in shadow $digest executing does not bind selected as it should be. 由于未知原因,shadow $ digest执行中的AngularJS未按预期绑定。 I have got to use jQuery to set the selected. 我必须使用jQuery来设置所选。 It`s important! 这很重要! AngularJS, in shadow, adds the prefix to the value of the attr "value" for generated by ng-repeat options. 阴影中的AngularJS将前缀添加到由ng-repeat选项生成的attr“值”的值。 For int it is "number:". 对于int,它是“数字:”。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM