получение ng-объекта, выбранного с помощью ng-change

313

Учитывая следующий элемент выбора

<select ng-options="size.code as size.name for size in sizes " 
        ng-model="item.size.code" 
        ng-change="update(MAGIC_THING)">
</select>

Есть ли способ , чтобы получить MAGIC_THING быть равно выбранным размером, поэтому у меня есть доступ к size.nameи size.codeв моем контроллере?

size.code влияет на многие другие части приложения (URL-адреса изображений и т. д.), но когда item.size.codeобновляется ng-модель , она также item.size.nameдолжна обновляться для пользовательского контента. Я предполагаю, что правильный способ сделать это - захват события изменения и установка значений внутри моего контроллера, но я не уверен, что я могу передать в обновление, чтобы получить правильные значения.

Если это совершенно неправильный путь, я бы хотел знать правильный путь.

Патрик
источник

Ответы:

488

Вместо того, чтобы установить ng-модель для item.size.code, как насчет установки его в размер:

<select ng-options="size as size.name for size in sizes" 
   ng-model="item" ng-change="update()"></select>

Тогда в вашем update()методе $scope.itemбудет установлен выбранный в данный момент элемент.

И любой необходимый код item.size.codeможет получить это свойство через $scope.item.code.

Скрипки .

Обновление на основе дополнительной информации в комментариях:

Затем используйте другое свойство $ scope для вашей выбранной модели ng:

<select ng-options="size as size.name for size in sizes" 
   ng-model="selectedItem" ng-change="update()"></select>

контроллер:

$scope.update = function() {
   $scope.item.size.code = $scope.selectedItem.code
   // use $scope.selectedItem.code and $scope.selectedItem.name here
   // for other stuff ...
}
Марк Райкок
источник
1
Если я устанавливаю свою модель как элемент, как мне предварительно выбрать значение?
Патрик
5
Поместите это в свой <select>: ng-init = "item = sizes [0]"
Марк Раджкок
Большое спасибо за вашу помощь, но я не думаю, что поделился достаточно ситуацией. Элемент - это объект, который создается загрузкой страницы. массив размеров объектов вступает в силу при взаимодействии пользователя с кнопкой редактирования, поэтому, если я сделаю это, он переопределит весь объект элемента. Мне нужен способ создать набор опций в поле выбора, которое предварительно выбирает значение из совершенно отдельной части объекта данных.
Патрик
14
Это правда? Кажется, что обработчик ng-change запускается до обновления ng-модели, поэтому попытка $ scope.item.size.code = $ scope.selectedItem.code не всегда может дать вам обновленное значение модели. Кто-нибудь видел это при использовании ng-change?
Карл
6
Думаю, что ничто не мешает вам сделать это:ng-model="selectedItem" ng-change="update(selectedItem)"
Рис ван дер Варден
52

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

 <select ng-options='t.name for t in templates'
                  ng-change='selectedTemplate(t.url)'></select>

script.js

 $scope.selectedTemplate = function(pTemplate) {
    //Your logic
    alert('Template Url is : '+pTemplate);
}
Дивьеш Рупавала
источник
5
Этот ответ на вопрос, в то время как принятый дает альтернативу
Redben
1
где вы инициализируете или получаете переменную шаблона?
Кэт Лим Руис
29
Это работает без указания модели? Я получаю эту ошибку: контроллер 'ngModel', требуемый директивой 'select', не может быть найден!
фер
8
ngModel определенно требуется для выбранных элементов, согласно документации. Другие директивы являются необязательными, но это не так.
Мнемия
26
Это не работает! У ng-change нет доступа к временной переменной (t), созданной внутри ng-options.
Мусор
16

Вы также можете попробовать это:

<select  ng-model="selectedItem" ng-change="update()">
<option ng-repeat="item in items" ng-selected="selectedItem == item.Id" value="{{item.Id}}">{{item.Name}}</option>
</select>
Сладкая жизнь
источник
2
Это решение хорошо, если вам нужно отформатировать значение. Используя только метод выбора, я не мог легко отформатировать значение.
Мбокил
7

Если ответ Дивеша Рупавалы не работает (передача текущего элемента в качестве параметра), см. onChanged()Функцию в этом Plunker. Он использует this:

http://plnkr.co/edit/B5TDQJ

abbaf33f
источник
2
<select ng-model="item.size.code">
<option ng-repeat="size in sizes" ng-attr-value="size.code">{{size.name}}          </option>
</select>
Джинеш Вария
источник
11
Используйте ng-options вместо ng-repeat при выборе.
Джепсер Бернардино
12
@JepserBernardino иногда вам необходим более тонкий доступ к <option>, например, для стилизации некоторых специальных / стандартных параметров независимо от того, выбраны они или нет
Ekus
2

//Javascript
$scope.update = function () {
    $scope.myItem;
    alert('Hello');
}
<!--HTML-->
<div class="form-group">
     <select name="name"
             id="id" 
             ng-model="myItem" 
             ng-options="size as size.name for size in sizes"
             class="form-control" 
             ng-change="update()"
             multiple
             required>
     </select>
</div>

Если вы хотите написать, имя, идентификатор, класс, несколько, обязательно, вы можете написать таким образом.

Barış çıracı
источник
1

Это может дать вам некоторые идеи

.NET C # Посмотреть модель

public class DepartmentViewModel
{
    public int Id { get; set; }
    public string Name { get; set; }
}

.NET C # Web Api Controller

public class DepartmentController : BaseApiController
{
    [HttpGet]
    public HttpResponseMessage Get()
    {
        var sms = Ctx.Departments;

        var vms = new List<DepartmentViewModel>();

        foreach (var sm in sms)
        {
            var vm = new DepartmentViewModel()
            {
                Id = sm.Id,
                Name = sm.DepartmentName
            };
            vms.Add(vm);
        }

        return Request.CreateResponse(HttpStatusCode.OK, vms);
    }

}

Угловой контроллер:

$http.get('/api/department').then(
    function (response) {
        $scope.departments = response.data;
    },
    function (response) {
        toaster.pop('error', "Error", "An unexpected error occurred.");
    }
);

$http.get('/api/getTravelerInformation', { params: { id: $routeParams.userKey } }).then(
   function (response) {
       $scope.request = response.data;
       $scope.travelerDepartment = underscoreService.findWhere($scope.departments, { Id: $scope.request.TravelerDepartmentId });
   },
    function (response) {
        toaster.pop('error', "Error", "An unexpected error occurred.");
    }
);

Угловой шаблон:

<div class="form-group">
    <label>Department</label>
    <div class="left-inner-addon">
        <i class="glyphicon glyphicon-hand-up"></i>
        <select ng-model="travelerDepartment"
                ng-options="department.Name for department in departments track by department.Id"
                ng-init="request.TravelerDepartmentId = travelerDepartment.Id"
                ng-change="request.TravelerDepartmentId = travelerDepartment.Id"
                class="form-control">
            <option value=""></option>
        </select>
    </div>
</div>
meffect
источник
1

Вам нужно использовать «track by», чтобы объекты можно было правильно сравнивать. В противном случае Angular будет использовать собственный способ сравнения объектов с помощью js.

Таким образом, ваш пример кода изменится на -

    <select ng-options="size.code as size.name
 for size in sizes track by size.code" 
ng-model="item.size.code"></select>
dworrad
источник
1

Фильтр AngularJS сработал для меня.

Предполагая , что code/idявляется уникальным , мы можем отфильтровать этот конкретный объект с AngularJS - х filterи работы с выбранными объектами недвижимости. Рассматривая пример выше:

<select ng-options="size.code as size.name for size in sizes" 
        ng-model="item.size.code" 
        ng-change="update(MAGIC_THING); search.code = item.size.code">
</select>

<!-- OUTSIDE THE SELECT BOX -->

<h1 ng-repeat="size in sizes | filter:search:true"
    ng-init="search.code = item.size.code">
  {{size.name}}
</h1>

Теперь есть 3 важных аспекта этого :

  1. ng-init="search.code = item.size.code"- при инициализации h1элемента вне selectполя установите для фильтра фильтра выбранную опцию .

  2. ng-change="update(MAGIC_THING); search.code = item.size.code"- когда вы измените выбор ввода, мы запустим еще одну строку, которая установит поисковый запрос на текущий выбранный item.size.code.

  3. filter:search:true- Перейти trueк фильтру, чтобы включить строгое соответствие .

Вот и все. Если size.codeэто уникальный идентификатор , у нас будет только один h1элемент с текстом size.name.

Я проверил это в моем проекте, и это работает.

Удачи

Акаша
источник
0

Это самый чистый способ получить значение из списка опций углового выбора (кроме Id или Text). Предполагая, что у вас есть продукт, подобный этому на вашей странице:

<select ng-model="data.ProductId"
        ng-options="product.Id as product.Name for product in productsList"
        ng-change="onSelectChange()">
</select>

Затем в вашем контроллере установите функцию обратного вызова так:

    $scope.onSelectChange = function () {
        var filteredData = $scope.productsList.filter(function (response) {
            return response.Id === $scope.data.ProductId;
        })
        console.log(filteredData[0].ProductColor);
    }

Объяснено просто: поскольку событие ng-change не распознает элементы опций в select, мы используем ngModel, чтобы отфильтровать выбранный Item из списка опций, загруженного в контроллер.

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

        $scope.onSelectChange = function () {
            $timeout(function () {
            var filteredData = $scope.productsList.filter(function (response) {
                return response.Id === $scope.data.ProductId;
            })
            console.log(filteredData[0].ProductColor);
            }, 100);
        };
Саги
источник