Как установить свойство value в ng-options AngularJS?

вот что, кажется, беспокоит многих людей (включая меня).

при использовании ng-options директива в AngularJS для заполнения опций для <select> tag, я не могу понять, как установить значение для опции. Документация для этого действительно неясна - по крайней мере, для такого простака, как я.

Я могу установить текст для опции легко так:

ng-options="select p.text for p in resultOptions"

, когда resultOptions например:

[
    {
        "value": 1,
        "text": "1st"
    },
    {
        "value": 2,
        "text": "2nd"
    }
]

это должно быть (и вероятно, это) самая простая вещь, чтобы установить значения опций, но до сих пор я просто не понимаю.

27 ответов


посмотреть ngOptions

ngOptions(опционально) – {comprehension_expression=} – в одном из следующие формы:

для источников данных массива: 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 track by trackexpr для источников данных объекта: 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

в вашем случае, она должна будь

array = [{ "value": 1, "text": "1st" }, { "value": 2, "text": "2nd" }];

<select ng-options="obj.value as obj.text for obj in array"></select>

обновление

С обновлениями на AngularJS теперь можно установить фактическое значение для на select элемент track by выражение.

<select ng-options="obj.text for obj in array track by obj.value">
</select>

Как запомнить эту гадость

для всех людей, которым трудно запомнить эту синтаксическую форму: я согласен, что это не самый простой или красивый синтаксис. Этот синтаксис является своего рода расширенной версией понимания списка Python и знание этого помогает мне очень легко запомнить синтаксис. Это что-то вроде этого:

Python-кода:

my_list = [x**2 for x in [1, 2, 3, 4, 5]]
> [1, 4, 9, 16, 25]

# Let people to be a list of person instances
my_list2 = [person.name for person in people]
> my_list2 = ['Alice', 'Bob']

это фактически тот же синтаксис, что и первый из перечисленных выше. Однако, в <select> нам обычно нужно различать фактическое значение в коде и показанный текст (ярлык) в <select> элемент.

как, нам нужно person.id в коде, но мы не хотим показать id пользователю; мы хотим показать его имя. Также, мы не заинтересованы в person.name в коде. Вот идет as ключевое слово для маркировки материала. Так он становится такой:

person.id as person.name for person in people

или, вместо person.id нам может понадобиться person экземпляров/ссылка сама. См. ниже:

person as person.name for person in people

для объектов JavaScript применяется тот же метод. Просто помните, что элементы в объекте деконструированы с помощью (key, value) пар.


как атрибуты value получают свое значение:

  • при использовании массива в качестве источника данных, это будет индекс элемента массива в каждой итерации;
  • при использовании объекта в качестве источника данных, это будет имя свойства в каждой итерации.

поэтому в вашем случае это должно быть:

obj = { '1': '1st', '2': '2nd' };

<select ng-options="k as v for (k,v) in obj"></select>

у меня тоже эта проблема. Я не смог установить свое значение в NG-options. Каждый вариант, который был создан с 0, 1, ..., n.

чтобы сделать это правильно, я сделал что-то вроде этого в моих ng-options:

HTML-код:

<select ng-options="room.name for room in Rooms track by room.price">
    <option value="">--Rooms--</option>
</select>

Я использую "track by", чтобы установить все мои значения с room.price.

(этот пример отстой: потому что, если бы было более одной цены, равной, код потерпел бы неудачу. Так что не забудьте иметь разные ценности.)

в формате JSON:

$scope.Rooms = [
            { name: 'SALA01', price: 100 },
            { name: 'SALA02', price: 200 },
            { name: 'SALA03', price: 300 }
        ];

я узнал это из сообщения в блоге как установить начальное выбранное значение элемента select с помощью Angular.JS ng-опции и трек по.

посмотреть видео. Это хороший класс :)


Если вы хотите изменить значение ваших option элементы, потому что форма в конечном итоге будет представлен на сервер, вместо этого

<select name="text" ng-model="text" ng-options="select p.text for p in resultOptions"></select>

вы можете сделать это:

<select ng-model="text" ng-options="select p.text for p in resultOptions"></select>
<input type="hidden" name="text" value="{{ text }}" />

ожидаемое значение будет отправлено через форму под правильным именем.


для отправки пользовательского значения my_hero на сервер с помощью обычной форме представить:

в формате JSON:

"heroes": [
  {"id":"iron", "label":"Iron Man Rocks!"},
  {"id":"super", "label":"Superman Rocks!"}
]

HTML-код:

<select ng-model="hero" ng-options="obj.id as obj.label for obj in heroes"></select>
<input type="hidden" name="my_hero" value="{{hero}}" />

сервер получит либо iron или super как значение my_hero.

это похоже на ответ @neemzy, но указание отдельных данных для .


получается, что ng-options сложно (возможно, расстраивает) использовать, но на самом деле у нас есть проблема с архитектурой.

AngularJS служит платформой MVC для динамического приложения HTML+JavaScript. Хотя его компонент (V)iew предлагает HTML-шаблоны, его основная цель-подключить действия пользователя через контроллер к изменениям в модели. Поэтому соответствующий уровень абстракции, от которого работать в AngularJS, это select element устанавливает значение в модели в значение из запроса.

  • то, как строка запроса представляется пользователю, является (V)проблемой iew и ng-options предоставляет for ключевое слово, чтобы диктовать, каким должно быть содержимое элемента option то есть p.text for p in resultOptions.
  • то, как выбранная строка представлена серверу, является проблемой (M)odel. Поэтому ng-options предоставляет as ключевое слово, чтобы указать, что значение передается модели, в k as v for (k,v) in objects.

правильное решение это проблема, то архитектурный характер и включает в себя рефакторинг HTML так, что (M)odel выполняет серверную связь, когда это необходимо (вместо пользователя, отправляющего форму).

если HTML-страница MVC не нужна для решения проблемы: затем используйте только часть генерации HTML компонента AngularJS (V)iew. В этом случае следуйте той же схеме, что используется для генерации таких элементов, как &lt;li /&gt;'S под &lt;ul /&gt;и поместите ng-repeat на элемент опции:

<select name=“value”>
    <option ng-repeat=“value in Model.Values” value=“{{value.value}}”>
        {{value.text}}
    </option>
</select>

As параметр, всегда можно переместить атрибут name элемента select в скрытый элемент ввода:

<select ng-model=“selectedValue” ng-options=“value.text for value in Model.Values”>
</select>
<input type=“hidden” name=“value” value=“{{selectedValue}}” />

вы можете сделать это:

<select ng-model="model">
    <option value="">Select</option>
    <option ng-repeat="obj in array" value="{{obj.id}}">{{obj.name}}</option>
</select>

-- UPDATE

после некоторых обновлений, пользователей frm.adiputraС намного лучше. Код:

obj = { '1': '1st', '2': '2nd' };
<select ng-options="k as v for (k,v) in obj"></select>

сегодня я некоторое время боролся с этой проблемой. Я прочитал документацию AngularJS, это и другие сообщения и несколько блогов, к которым они приводят. Все они помогли мне найти более тонкие детали, но в конце концов это просто кажется запутанной темой. В основном из-за многих синтаксических нюансов ng-options.

в конце концов, для меня все свелось к более или менее.

учитывая область, настроенную следующим образом:

        //Data used to populate the dropdown list
        $scope.list = [
           {"FirmnessID":1,"Description":"Soft","Value":1},         
           {"FirmnessID":2,"Description":"Medium-Soft","Value":2},
           {"FirmnessID":3,"Description":"Medium","Value":3}, 
           {"FirmnessID":4,"Description":"Firm","Value":4},     
           {"FirmnessID":5,"Description":"Very Firm","Value":5}];

        //A record or row of data that is to be save to our data store.
        //FirmnessID is a foreign key to the list specified above.
        $scope.rec = {
           "id": 1,
           "FirmnessID": 2
        };

это все, что мне нужно получите желаемый результат:

        <select ng-model="rec.FirmnessID"
                ng-options="g.FirmnessID as g.Description for g in list">
            <option></option>
        </select>   

обратите внимание, что я не использовал track by. Используя track by выбранный элемент всегда возвращает объект, соответствующий FirmnessID, а не сам FirmnessID. Теперь это соответствует моим критериям, которые заключаются в том, что он должен возвращать числовое значение, а не объект, и использовать ng-options для повышения производительности он обеспечивает, не создавая новую область для каждого созданного параметра.

кроме того, мне нужна была пустая первая строка, поэтому я просто добавлено <option> до <select> элемент.

здесь Plunkr это показывает мою работу.


вместо использования новой функции "track by" вы можете просто сделать это с массивом, если хотите, чтобы значения были такими же, как текст:

<select ng-options="v as v for (k,v) in Array/Obj"></select>

обратите внимание на разницу между стандартным синтаксисом, который сделает значения ключами объекта / массива, и, следовательно, 0,1,2 и т. д. для массива:

<select ng-options"k as v for (k,v) in Array/Obj"></select>

k как v становится v как v.

я обнаружил это лишь на основе здравого смысла, глядя на синтаксис. (k, v) является оператор actual, который разбивает массив / объект на пары ключевых значений.

в операторе "k как v" k будет значением, а v будет текстовой опцией, отображаемой пользователю. Я думаю, что "трек мимо" грязный и излишний.


Это лучше всего подходит для всех сценариев по мне:

<select ng-model="mySelection.value">
   <option ng-repeat="r in myList" value="{{r.Id}}" ng-selected="mySelection.value == r.Id">{{r.Name}}
   </option>
</select>

где вы можете использовать свою модель для привязки данных. Вы получите значение как объект будет содержать и выбор по умолчанию на основе вашего сценария.


вот как я решил эту. Я отследил select по значению и установил свойство выбранного элемента в модель в моем коде JavaScript.

Countries =
[
    {
        CountryId = 1, Code = 'USA', CountryName = 'United States of America'
    },
    {
       CountryId = 2, Code = 'CAN', CountryName = 'Canada'
    }
]
<select ng-model="vm.Enterprise.AdminCountry" ng-options="country.CountryName for country in vm.Countries track by country.CountryId">

vm мой контроллер и страны в контроллер извлечены из сервиса {CountryId =1, Code = 'USA', CountryName='United States of America'}.

когда я выбрал другую страну из раскрывающегося списка select и разместил свою страницу с "сохранить", я получил правильную привязку к стране.


на ng-options директива не устанавливает атрибут value на <options> элементы массивов:

используя limit.value as limit.text for limit in limits означает:

установить как limit.text
сохранить limit.value значение в поле выберите это ng-model

см. вопрос переполнения стека AngularJS ng-параметры, не отображающие значения.


<select ng-model="color" ng-options="(c.name+' '+c.shade) for c in colors"></select><br>

правильный ответ на этот вопрос был предоставлен frm.adiputra, поскольку в настоящее время это единственный способ явно контролировать атрибут value элементов option.

однако я просто хотел подчеркнуть, что" select " не является ключевым словом в этом контексте, но это просто заполнитель для выражения. Пожалуйста, обратитесь к следующему списку для определения выражения" select", а также других выражений, которые могут быть используется в директиве ng-options.

использование select, как показано в вопросе:

ng-options='select p.text for p  in resultOptions'

по сути неверно.

основываясь на списке выражений, кажется, что trackexpr может использоваться для указания значения, когда параметры заданы в массиве объектов, но он использовался только с группировкой.


из документации AngularJS для ng-options:

  • массив / объект: выражение, которое вычисляет массив / объект для повторите.
  • стоимостью: локальной переменной, которая будет ссылаться на каждый элемент в массив или каждое значение свойства объекта во время итерации.
  • ключ: локальной переменной, которая будет ссылаться на имя свойства в объекте во время итерация.
  • метка: результатом этого выражения будет метка для элемент. Выражение скорее всего см. значение переменная (например, значение.параметр propertyName.)
  • выберите: результат этого выражения будет привязан к модели родительского элемента. Если не задано, select expression по умолчанию будет иметь значение value.
  • группа: результат этого выражения будет использоваться для группировки параметров с помощью DOM элемент.
  • trackexpr: используется при работе с массивом объектов. Результатом этого выражения будет используемый для идентификации объектов в массиве. В trackexpr скорее всего относятся к переменная значения (например, value.параметр propertyName.)

выбор элемента в NG-options может быть немного сложным в зависимости от того, как вы устанавливаете источник данных.

после борьбы с ними некоторое время, я закончил тем, что делал образец с наиболее распространенными источниками данных я использую. Вы можете найти его здесь:

http://plnkr.co/edit/fGq2PM?p=preview

теперь, чтобы сделать ng-options работать, вот некоторые вещи, чтобы рассмотреть:

  1. обычно вы получаете параметры из одного источника и выбранное значение из другой. Например:
    • состояния:: данные для ng-options
    • пользователей.state :: опция для установки как selected
  2. основываясь на 1, самая простая/логическая вещь-заполнить select одним источником, а затем установить выбранное значение через код. Редко было бы лучше получить смешанный набор данных.
  3. AngularJS позволяет выбрать элементы управления, чтобы держать больше, чем key | label. Многие онлайн-примеры помещают объекты в качестве "ключа", и если вам нужна информация объект устанавливает его таким образом, иначе Используйте конкретное свойство, которое вам нужно в качестве ключа. (Идентификатор, код, и т. д.. Как в Примере plckr)
  4. способ установки значения раскрывающегося списка / выбора элемента управления зависит от #3,

    • если выпадающий ключ является одним свойством (как и во всех примерах в plunkr), вы просто установите его, например: $scope.dropdownmodel = $scope.user.state;
    • если вы устанавливаете объект как ключ, то вам нужно зациклить ринв варианты, даже назначать объект не установит элемент как выбранный, так как они будут иметь разные hashkeys, например:

      for (var i = 0, len = $scope.options.length; i < len; i++) {
        if ($scope.options[i].id == savedValue) { // Your own property here:
          console.log('Found target! ');
          $scope.value = $scope.options[i];
          break;
        }
      }
      

вы можете заменить savedValue для того же свойства в другом объекте,$scope.myObject.myProperty.


для меня ответ Бруно Гомеса - Это лучший ответ.

но на самом деле вам не нужно беспокоиться о настройке свойства value параметров select. AngularJS позаботится об этом. Позвольте мне объяснить подробно.

пожалуйста, рассмотрите эту скрипку

angular.module('mySettings', []).controller('appSettingsCtrl', function ($scope) {

    $scope.timeFormatTemplates = [{
        label: "Seconds",
        value: 'ss'
    }, {
        label: "Minutes",
        value: 'mm'
    }, {
        label: "Hours",
        value: 'hh'
    }];


    $scope.inactivity_settings = {
        status: false,
        inactive_time: 60 * 5 * 3, // 15 min (default value), that is, 900 seconds
        //time_format: 'ss', // Second (default value)
        time_format: $scope.timeFormatTemplates[0], // Default seconds object
    };

    $scope.activity_settings = {
        status: false,
        active_time: 60 * 5 * 3, // 15 min (default value), that is,  900 seconds
        //time_format: 'ss', // Second (default value)
        time_format: $scope.timeFormatTemplates[0], // Default seconds object
    };

    $scope.changedTimeFormat = function (time_format) {
        'use strict';

        console.log('time changed');
        console.log(time_format);
        var newValue = time_format.value;

        // do your update settings stuffs
    }
});

Как вы можете видеть в выводе скрипки, что бы вы ни выбрали для опций select box, это ваше пользовательское значение или 0, 1, 2 автоматически генерируемое значение AngularJS, это не значение в выводе, если вы не используете jQuery или любую другую библиотеку для доступа к значению параметров поля со списком select и соответствующего управления им.


через год после вопрос, я должен был найти ответ на этот вопрос не дал ответа, по крайней мере для меня.

вы спросили, Как выбрать вариант, но никто не сказал, что эти две вещи не так же:

Если у нас есть такие варианты:

$scope.options = [
    { label: 'one', value: 1 },
    { label: 'two', value: 2 }
  ];

и мы пытаемся установить параметр по умолчанию, как это:

$scope.incorrectlySelected = { label: 'two', value: 2 };

Это не работа, но если вы попытаетесь выбрать опцию, как это:

$scope.correctlySelected = $scope.options[1];

Это работа.

хотя эти два объекта имеют одинаковые свойства, AngularJS рассматривает их как разные, потому что AngularJS сравнивает ссылка.

взгляните на скрипку http://jsfiddle.net/qWzTb/.


объекта:

<select ng-model="mySelect" ng-options="key as value for (key, value) in object"></select>

разработчикам всегда больно с ng-опциями. Например: получение пустого / пустого выбранного значения в теге select. Особенно при работе с объектами JSON в NG-options это становится более утомительным. Здесь я сделал несколько упражнений на эту тему.

цель: повторите массив объектов JSON через ng-option и установите выбранный первый элемент.

данные:

someNames = [{"id":"1", "someName":"xyz"}, {"id":"2", "someName":"abc"}]

в теге select я должен был показать xyz и abc, где xyz должен быть выбран без много усилий.

HTML-код:

<pre class="default prettyprint prettyprinted" style=""><code>
    &lt;select class="form-control" name="test" style="width:160px"    ng-options="name.someName for name in someNames" ng-model="testModel.test" ng-selected = "testModel.test = testModel.test || someNames[0]"&gt;
&lt;/select&gt;
</code></pre>

выше пример кода, Вы можете выйти из этого преувеличения.

еще один ссылка:


учебник угловое.JS: NG-SELECT И NG-OPTIONS помог мне решить проблему:

<select id="countryId"
  class="form-control"
  data-ng-model="entity.countryId"
  ng-options="value.dataValue as value.dataText group by value.group for value in countries"></select>

используйте свойство track by, которое различает значения и метки в поле выбора.

пожалуйста

<select ng-options="obj.text for obj in array track by obj.value"></select>

который будет назначать метки с текстом и значением со значением (из массива)


Вы можете использовать ng-options для достижения привязки тега select к значению и отображать элементы

при использовании этого источника данных

countries : [
              {
                 "key": 1,
                 "name": "UAE"
             },
              {
                  "key": 2,
                  "name": "India"
              },
              {
                  "key": 3,
                  "name": "OMAN"
              }
         ]

вы можете использовать НИЖЕ, чтобы привязать тег select к значению и имени

<select name="text" ng-model="name" ng-options="c.key as c.name for c in countries"></select>

он работает


<select ng-model="output">
   <option ng-repeat="(key,val) in dictionary" value="{{key}}">{{val}}</option>
</select>

запустите фрагмент кода и посмотрите варианты. Вот примечание для быстрого понимания

  1. Пример 1 (выбор объекта): -ng-option="os.name for os in osList track by os.id". Вот!--4--> важно & должно быть туда и os.id as не должен перед os.name.

    • на ng-model="my_os" следует установить объект с ключом как id как my_os={id: 2}.
  2. Пример 2(Выбор значения ) :- ng-option="os.id as os.name for os in osList". Вот!--4--> не должен туда и os.id as должно быть там перед os.name.

    • на ng-model="my_os" должно быть установлено значение my_os= 2

фрагмент кода Rest объяснит.

angular.module('app', []).controller('ctrl', function($scope, $timeout){
  
  //************ EXAMPLE 1 *******************
  $scope.osList =[
    { id: 1, name :'iOS'},
    { id: 2, name :'Android'},
    { id: 3, name :'Windows'}
  ]
  $scope.my_os = {id: 2};
  
  
  //************ EXAMPLE 2 *******************
  $timeout(function(){
    $scope.siteList = [
          { id: 1, name: 'Google'},
          { id: 2, name: 'Yahoo'},
          { id: 3, name: 'Bing'}
        ];
   }, 1000);
    
    $scope.my_site = 2;
  
    $timeout(function(){
      $scope.my_site = 3;
    }, 2000);
})
fieldset{
  margin-bottom: 40px;
  }
strong{
  color:red;
  }
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.10/angular.min.js"></script>

<div ng-app="app" ng-controller="ctrl">

  <!--//************ EXAMPLE 1 *******************-->
  <fieldset>
    <legend>Example 1 (Set selection as <strong>object</strong>)</legend>
    
    <select ng-model="my_os" ng-options="os.name for os in osList track by os.id">
        <option value="">--Select--</option>
      </select>
    {{my_os}}
    
  </fieldset>
  
  
  <!--//************ EXAMPLE 2 *******************-->
  <fieldset>
    <legend>Example 2 (Set selection as <strong>value</strong>. Simulate ajax)</legend>
      <select ng-model="my_site" ng-options="site.id as site.name for site in siteList">
        <option value="">--Select--</option>
      </select>
      {{my_site}}
  </fieldset>
  
</div>

как многие говорили раньше, если у меня есть данные, что-то вроде этого:

countries : [
              {
                 "key": 1,
                 "name": "UAE"
             },
              {
                  "key": 2,
                  "name": "India"
              },
              {
                  "key": 3,
                  "name": "OMAN"
              }
         ]

Я бы использовал его как:

<select
    ng-model="selectedCountry"
    ng-options="obj.name for obj  in countries">
</select>

в контроллере необходимо задать начальное значение, чтобы избавиться от первого пустого элемента:

 $scope.selectedCountry = $scope.countries[0];

 // You need to watch changes to get selected value
 $scope.$watchCollection(function() {
   return $scope.selectedCountry
 }, function(newVal, oldVal) {
     if (newVal === oldVal) {
       console.log("nothing has changed " + $scope.selectedCountry)
     } 
     else {
       console.log('new value ' + $scope.selectedCountry)
     }
 }, true)

вот как я решаю эту проблему в устаревших приложений:

в HTML:

ng-options="kitType.name for kitType in vm.kitTypes track by kitType.id" ng-model="vm.itemTypeId"

В JavaScript:

vm.kitTypes = [
    {"id": "1", "name": "Virtual"},
    {"id": "2", "name": "Physical"},
    {"id": "3", "name": "Hybrid"}
];

...

vm.itemTypeId = vm.kitTypes.filter(function(value, index, array){
    return value.id === (vm.itemTypeId || 1);
})[0];

мой HTML отображает значение параметра правильно.


директива ngOptions:

$scope.items = [{name: 'a', age: 20},{ name: 'b', age: 30},{ name: 'c', age: 40}];
  • Case-1) метка для значения в массиве:

    <div>
        <p>selected item is : {{selectedItem}}</p>
        <p> age of selected item is : {{selectedItem.age}} </p>
        <select ng-model="selectedItem" ng-options="item.name for item in items">
        </select>
    </div>
    

объяснение вывода (предположим, 1-й элемент выбран):

selectedItem = {name: 'a', age: 20} // [по умолчанию выбранный элемент равен значению элемент]

selectedItem.возраст = 20

  • случае-2) выберите в качестве метки значение в массиве:

    <div>
        <p>selected item is : {{selectedItem}}</p>
        <select ng-model="selectedItem" ng-options="item.age as item.name for item in items">
        </select>
    </div>
    

объяснение вывода (предположим, выбран 1-й элемент): для selecteditem = 20 // [выберите часть товар.возраст!--17-->]