AngularJS - атрибут value для выбора
Исходные данные JSON:
[
{"name":"Alabama","code":"AL"},
{"name":"Alaska","code":"AK"},
{"name":"American Samoa","code":"AS"},
...
]
Я пытаюсь
ng-options="i.code as i.name for i in regions"
но я получаю:
<option value="?" selected="selected"></option>
<option value="0">Alabama</option>
<option value="1">Alaska</option>
<option value="2">American Samoa</option>
пока я ожидаю получить:
<option value="AL">Alabama</option>
<option value="AK">Alaska</option>
<option value="AS">American Samoa</option>
Итак, как получить атрибуты стоимости и избавиться от "?" пункт?
Кстати, если я установил $scope.regions в статический JSON вместо результата запроса AJAX, пустой элемент исчезнет.
Ответы
Ответ 1
То, что вы впервые пробовали, должно работать, но HTML не то, что мы ожидаем. Я добавил параметр для обработки начального случая "без элементов":
<select ng-options="region.code as region.name for region in regions" ng-model="region">
<option style="display:none" value="">select a region</option>
</select>
<br>selected: {{region}}
Вышеприведенный HTML-код:
<select ng-options="..." ng-model="region" class="...">
<option style="display:none" value class>select a region</option>
<option value="0">Alabama</option>
<option value="1">Alaska</option>
<option value="2">American Samoa</option>
</select>
Fiddle
Даже если Angular использует числовые целые числа для значения, модель (т.е. $scope.region) будет установлена на AL, AK или AS, если требуется. (Числовое значение используется Angular для поиска правильной записи массива, когда в списке выбран вариант.)
Это может сбивать с толку, когда сначала узнаете, как Angular реализует свою директиву "select".
Ответ 2
Вы не можете этого сделать, если сами не создадите их в ng-repeat.
<select ng-model="foo">
<option ng-repeat="item in items" value="{{item.code}}">{{item.name}}</option>
</select>
НО... это, вероятно, не стоит. Лучше оставить его функцией в соответствии с конструкцией и позволить Angular обрабатывать внутренние работы. Angular использует этот индекс таким образом, чтобы вы могли фактически использовать весь объект в качестве значения. Таким образом, вы можете использовать выпадающее связывание, чтобы выбрать целое значение, а не просто строку, что довольно удивительно:
<select ng-model="foo" ng-options="item as item.name for item in items"></select>
{{foo | json}}
Ответ 3
Если вы используете параметр track by
, атрибут value
правильно написан, например:
<div ng-init="a = [{label: 'one', value: 15}, {label: 'two', value: 20}]">
<select ng-model="foo" ng-options="x for x in a track by x.value"/>
</div>
дает:
<select>
<option value="" selected="selected"></option>
<option value="15">one</option>
<option value="20">two</option>
</select>
Ответ 4
Если модель, указанная для раскрывающегося списка, не существует, то angular будет генерировать пустой элемент. Таким образом, вам нужно будет явно указать модель на select следующим образом:
<select ng-model="regions[index]" ng-options="....">
Обратите внимание на следующее, как было ответино ранее:
Почему у AngularJS есть пустая опция в выборе?, и это fiddle
Обновление: Попробуйте это вместо:
<select ng-model="regions[index].code" ng-options="i.code as i.name for i in regions">
</select>
or
<select ng-model="regions[2]" ng-options="r.name for r in regions">
</select>
Обратите внимание, что в элементе выбора нет пустого элемента.
Ответ 5
Вы можете изменить модель, чтобы выглядеть так:
$scope.options = {
"AL" : "Alabama",
"AK" : "Alaska",
"AS" : "American Samoa"
};
Затем используйте
<select ng-options="k as v for (k,v) in options"></select>
Ответ 6
Похоже, что фактически невозможно использовать "значение" выбора любым значимым способом как обычный элемент формы HTML, а также подключить его к Angular одобренным способом с помощью ng-options. В качестве компромисса мне пришлось поместить скрытый ввод рядом с моим выбором, и он отслеживает ту же модель, что и мой выбор, как это (все это очень упрощено из реального производственного кода для краткости):
HTML:
<select ng-model="profile" ng-options="o.id as o.name for o in profiles" name="something_i_dont_care_about">
</select>
<input name="profile_id" type="text" style="margin-left:-10000px;" ng-model="profile"/>
JavaScript:
App.controller('ConnectCtrl',function ConnectCtrl($scope) {
$scope.profiles = [{id:'xyz', name:'a profile'},{id:'abc', name:'another profile'}];
$scope.profile = -1;
}
Затем в моем серверном коде я просто искал params[:profile_id]
(это было приложение Rails, но тот же принцип применяется в любом месте). Поскольку скрытый вход отслеживает ту же модель, что и выбор, они остаются синхронно автоматически (для этого не требуется никакого дополнительного javascript). Это крутая часть Angular. Это почти компенсирует то, что он делает с атрибутом value как побочный эффект.
Интересно, что я нашел, что этот метод работал только с тегами ввода, которые не были скрыты (поэтому мне пришлось использовать margin-left: -10000px; трюк для перемещения ввода со страницы). Эти два варианта не помогли:
<input name="profile_id" type="text" style="display:none;" ng-model="profile"/>
и
<input name="profile_id" type="hidden" ng-model="profile"/>
Я чувствую, что это должно означать, что я что-то упускаю. Кажется слишком странным, что это проблема с Angular.
Ответ 7
вы можете использовать
state.name for state in states track by state.code
В случае состояний в массиве JSON состояние - это имя переменной для каждого объекта в массиве.
Надеюсь, что это поможет
Ответ 8
Попробуйте, как показано ниже:
var scope = $(this).scope();
alert(JSON.stringify(scope.model.options[$('#selOptions').val()].value));