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

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

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

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>

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


2
<select ng-model="item.size.code">
<option ng-repeat="size in sizes" ng-attr-value="size.code">{{size.name}}          </option>
</select>

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.


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>

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>

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


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);
        };
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.