Подтвердить что ты не робот

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, пустой элемент исчезнет.

4b9b3361

Ответ 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));