pobranie obiektu ng za pomocą ng-change

313

Biorąc pod uwagę następujący element wybierz

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

Czy istnieje sposób, aby uzyskać MAGIC_THING być równa aktualnie wybranego rozmiaru, więc mam dostęp do size.namei size.codew moim kontrolera?

size.code wpływa na wiele innych części aplikacji (adresy URL obrazów itp.), ale kiedy item.size.codezaktualizowany jest model ng , item.size.namenależy go również zaktualizować dla użytkowników stojących naprzeciwko. Zakładam, że poprawnym sposobem na to jest przechwycenie zdarzenia zmiany i ustawienie wartości w moim kontrolerze, ale nie jestem pewien, co mogę przekazać aktualizacji, aby uzyskać odpowiednie wartości.

Jeśli jest to całkowicie niewłaściwy sposób, chciałbym poznać właściwą drogę.

Patrick
źródło

Odpowiedzi:

488

Zamiast ustawiać model ng na item.size.code, co powiesz na ustawienie go na rozmiar:

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

Następnie w Twojej update()metodzie $scope.itemzostanie ustawiony na aktualnie wybrany element.

I niezależnie od potrzebnego kodu item.size.code, można uzyskać tę właściwość za pośrednictwem $scope.item.code.

Fiddle .

Aktualizacja w oparciu o więcej informacji w komentarzach:

Użyj innej właściwości $ scope dla wybranego modelu ng, a następnie:

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

Kontroler:

$scope.update = function() {
   $scope.item.size.code = $scope.selectedItem.code
   // use $scope.selectedItem.code and $scope.selectedItem.name here
   // for other stuff ...
}
Mark Rajcok
źródło
1
Jeśli ustawię mój model jako element, jak wstępnie wybrać wartość?
Patrick
5
Włóż to do swojego <select>: ng-init = "item = rozmiary [0]"
Mark Rajcok
Dziękuję bardzo za pomoc, ale nie sądzę, że podzieliłem się wystarczająco sytuacją. element to obiekt, który jest tworzony ładowanie strony. tablica rozmiarów obiektów pojawia się podczas interakcji użytkownika z przyciskiem edycji, więc jeśli to zrobię, zastąpi cały obiekt elementu. Potrzebuję sposobu na utworzenie szeregu opcji w polu wyboru, które wstępnie wybiera wartość z całkowicie oddzielnej części obiektu danych.
Patrick
14
Czy to prawda? Wygląda na to, że moduł obsługi zmiany ng jest uruchamiany przed zaktualizowaniem modelu ng, więc próba $ scope.item.size.code = $ scope.selectedItem.code może nie zawsze dać zaktualizowaną wartość modelu. Czy ktoś widział to podczas używania ng-change?
Karl
6
Chyba nie ma nic Cię powstrzymuje od robienia tego albo:ng-model="selectedItem" ng-change="update(selectedItem)"
Rhys van der Waerden
52

Możesz także uzyskać wybraną wartość bezpośrednio, używając następującego kodu

 <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);
}
Divyesh Rupawala
źródło
5
To pytanie odpowiada, podczas gdy zaakceptowane daje alternatywę
redben
1
gdzie inicjujesz lub otrzymujesz zmienną szablonu?
Kat Lim Ruiz
29
Czy to działa bez określenia modelu? Pojawia się ten błąd: nie można znaleźć kontrolera „ngModel” wymaganego przez dyrektywę „select”!
fer
8
ngModel jest zdecydowanie wymagany dla wybranych elementów, zgodnie z dokumentacją. Pozostałe dyrektywy są opcjonalne, ale ta nie jest.
mnemia
26
To nie działa! ng-change nie ma dostępu do zmiennej tymczasowej (t) utworzonej w opcjach ng.
Śmieci
16

możesz także spróbować tego:

<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>
Słodkie życie
źródło
2
To rozwiązanie jest dobre, jeśli musisz sformatować wartość. Używając tylko podejścia Select, nie mogłem łatwo sformatować wartości.
mbokil
7

Jeśli odpowiedź Divyesh Rupawala nie działa (przekazując bieżący element jako parametr), zobacz onChanged()funkcję w tym Plunkerze. Używa this:

http://plnkr.co/edit/B5TDQJ

abbaf33f
źródło
2
<select ng-model="item.size.code">
<option ng-repeat="size in sizes" ng-attr-value="size.code">{{size.name}}          </option>
</select>
Jignesh Variya
źródło
11
Użyj opcji ng zamiast ng-repeat w zaznaczeniu.
Jepser Bernardino
12
@JepserBernardino czasami potrzebujesz dokładniejszego dostępu do <option>, np. Aby stylizować niektóre specjalne / domyślne opcje niezależnie od tego, czy są wybrane, czy nie
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>

Jeśli chcesz pisać, nazwa, identyfikator, klasa, wielokrotność, wymagane, możesz pisać w ten sposób.

barış çıracı
źródło
1

To może dać ci kilka pomysłów

.NET C # Wyświetl model

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

Kontroler interfejsu API sieci Web .NET C #

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);
    }

}

Kontroler kątowy:

$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.");
    }
);

Szablon kątowy:

<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>
skuteczny
źródło
1

Musisz użyć opcji „śledź według”, aby obiekty mogły być poprawnie porównywane. W przeciwnym razie Angular użyje natywnego js do porównywania obiektów.

Twój przykładowy kod zmieni się na -

    <select ng-options="size.code as size.name
 for size in sizes track by size.code" 
ng-model="item.size.code"></select>
dworrad
źródło
1

Filtr AngularJS zadziałał dla mnie.

Zakładając, że code/idjest unikalny , możemy odfiltrować ten konkretny obiekt za pomocą AngularJS filteri pracować z właściwościami wybranych obiektów. Biorąc pod uwagę powyższy przykład:

<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>

Teraz są 3 ważne aspekty :

  1. ng-init="search.code = item.size.code"- przy inicjowaniu h1elementu poza selectpolem ustaw zapytanie filtru na wybraną opcję .

  2. ng-change="update(MAGIC_THING); search.code = item.size.code"- kiedy zmienisz wybrane wejście, uruchomimy jeszcze jedną linię, która ustawi zapytanie „search” na aktualnie wybrane item.size.code.

  3. filter:search:true- Przekaż truedo filtra, aby umożliwić ścisłe dopasowanie .

Otóż ​​to. Jeśli size.codejest unikalny , będziemy mieli tylko jeden h1element z tekstem size.name.

Przetestowałem to w moim projekcie i działa.

Powodzenia

Akash
źródło
0

Jest to najczystszy sposób na uzyskanie wartości z listy opcji wyboru kątowego (innej niż Id lub Tekst). Zakładając, że masz na stronie taki produkt:

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

Następnie w kontrolerze ustaw funkcję oddzwaniania w następujący sposób:

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

Po prostu wyjaśnione: Ponieważ zdarzenie ng-change nie rozpoznaje opcji w zaznaczeniu, używamy ngModel do odfiltrowania wybranego elementu z listy opcji załadowanej do kontrolera.

Ponadto, ponieważ zdarzenie jest uruchamiane przed aktualizacją ngModel, możesz uzyskać niepożądane wyniki, więc lepszym sposobem byłoby dodanie limitu czasu:

        $scope.onSelectChange = function () {
            $timeout(function () {
            var filteredData = $scope.productsList.filter(function (response) {
                return response.Id === $scope.data.ProductId;
            })
            console.log(filteredData[0].ProductColor);
            }, 100);
        };
Sagi
źródło