Работа с select с использованием AngularJS ng-options
Я читал об этом в других сообщениях, но я не мог понять это.
У меня есть массив,
$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.
Я прочитал выбор и попытался, но я не могу понять это.
8 ответов
Стоит отметить, что ngModel требуется для работы ngOptions... обратите внимание на ng-model="blah"
который говорит "установить $scope.blah для выбранного значения".
Попробуй это:
<select ng-model="blah" ng-options="item.ID as item.Title for item in items"></select>
Вот еще из документации AngularJS (если вы ее еще не видели):
для источников данных массива:
- метка для значения в массиве
- выбрать в качестве метки для значения в массиве
- метка группа по группе для значения в массиве = выбрать как метка группа по группе для значения в массиве
для источников данных объекта:
- метка для (ключ, значение) в объекте
- выбрать в качестве метки для (ключ, значение) в объекте
- пометить группу за группой для (ключ, значение) в объекте
- выбрать в качестве метки группу по группе для (ключ, значение) в объекте
Для пояснения значений тегов опций в AngularJS:
Когда вы используете ng-options
значения тегов option, записанных с помощью ng-options, всегда будут индексом элемента массива, к которому относится тег option. Это потому, что AngularJS фактически позволяет вам выбирать целые объекты с помощью элементов управления select, а не только примитивные типы. Например:
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>
Вышеуказанное позволит вам выделить весь объект в $scope.selectedItem
непосредственно. Дело в том, что с AngularJS вам не нужно беспокоиться о том, что находится в вашем теге option. Пусть AngularJS справится с этим; Вы должны заботиться только о том, что находится в вашей модели в вашем объеме.
Вот плункер, демонстрирующий поведение выше и показывающий выписанный HTML
Работа с опцией по умолчанию:
Есть несколько вещей, которые я не упомянул выше, касающихся опции по умолчанию.
Выбор первого варианта и удаление пустого параметра:
Вы можете сделать это, добавив простой 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>
Примечание: это может немного сойти с ума, если foo
случайно инициализируется к чему-то "ложному". В этом случае вы захотите обработать инициализацию foo
в вашем контроллере, скорее всего.
Настройка опции по умолчанию:
Это немного по-другому; здесь все, что вам нужно сделать, это добавить тег option как дочерний элемент вашего выбора с пустым атрибутом value, а затем настроить его внутренний текст:
<select ng-model="foo" ng-options="item as item.name for item in items">
<option value="">Nothing selected</option>
</select>
Примечание. В этом случае "пустая" опция останется там даже после выбора другой опции. Это не относится к поведению по умолчанию выбора в AngularJS.
Настраиваемая опция по умолчанию, которая скрывается после выбора:
Если вы хотите, чтобы настроенная опция по умолчанию исчезла после выбора значения, вы можете добавить атрибут 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>
Я изучаю AngularJS и тоже боролся с отбором. Я знаю, что на этот вопрос уже дан ответ, но я все же хотел поделиться еще одним кодом.
В моем тесте у меня есть два списка: марки автомобилей и модели автомобилей. Список моделей отключен, пока не будет выбрана какая-либо марка. Если выбор в списке марок позднее сбрасывается (устанавливается "Выбрать марку"), тогда список моделей снова отключается и его выбор также сбрасывается (на "Выбор модели"). Марки извлекаются как ресурс, а модели просто жестко запрограммированы.
Делает 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"};
}
Почему-то AngularJS позволяет мне запутаться. Их документация довольно ужасна по этому поводу. Более хорошие примеры вариаций будут приветствоваться.
Во всяком случае, у меня есть небольшое отклонение от ответа Бена Леша.
Мои коллекции данных выглядят так:
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>
по-прежнему приводит к тому, что значение опций будет индексом (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>
На этот вопрос уже дан ответ (кстати, действительно хороший и исчерпывающий ответ, предоставленный Беном), но я хотел бы добавить еще один элемент для полноты, который также может быть очень удобным.
В примере, предложенном Беном:
<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
длина строки заголовка.
Вы также можете использовать фильтры, например,
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"
дает вам ярлыки, какTitle (27 Sep 2015)
, если ваша модель имеет свойствоSomeDate
В 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>
Если вам нужен собственный заголовок для каждого параметра, 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>
Я надеюсь, что следующее будет работать для вас.
<select class="form-control"
ng-model="selectedOption"
ng-options="option.name + ' (' + (option.price | currency:'USD$') + ')' for option in options">
</select>
Это может быть полезно. Привязки не всегда работают.
<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. Выбранное значение было известно до заполнения списка, и оно было установлено. После выполнения запроса REST с помощью $http, опция list будет выполнена.
Но выбранная опция не установлена. По неизвестным причинам AngularJS в теневом $digest при выполнении не привязывает выбранный, как должно быть. Я должен использовать JQuery, чтобы установить выбранное. Это важно! AngularJS в тени добавляет префикс к значению атрибута "значение" для сгенерированных опциями ng-repeat. Для 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);
}
});
}