ottenere l'oggetto ng selezionato con ng-change


313

Dato il seguente elemento di selezione

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

C'è un modo per ottenere MAGIC_THING uguale alla dimensione attualmente selezionata, quindi ho accesso a size.namee size.codenel mio controller?

size.code influisce su molte altre parti dell'app (URL delle immagini, ecc.), ma quando il modello ng di item.size.codeviene aggiornato, item.size.namedeve essere aggiornato anche per l'utente che deve affrontare le cose. Suppongo che il modo corretto per farlo sia catturare l'evento change e impostare i valori all'interno del mio controller, ma non sono sicuro di cosa posso passare in aggiornamento per ottenere i valori corretti.

Se questo è completamente il modo sbagliato di farlo, mi piacerebbe sapere il modo giusto.

Risposte:


488

Invece di impostare ng-model su item.size.code, che ne dici di impostarlo su size:

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

Quindi, nel tuo update()metodo, $scope.itemverrà impostato l'elemento attualmente selezionato.

E qualunque codice sia necessario item.size.code, può ottenere quella proprietà tramite $scope.item.code.

Violino .

Aggiornamento basato su maggiori informazioni nei commenti:

Usa qualche altra proprietà $ scope per il tuo modello ng selezionato quindi:

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

controller:

$scope.update = function() {
   $scope.item.size.code = $scope.selectedItem.code
   // use $scope.selectedItem.code and $scope.selectedItem.name here
   // for other stuff ...
}

1
Se imposto il mio modello come articolo, come preselezionare un valore?
Patrick,

5
Inseriscilo nel tuo <select>: ng-init = "item =
size

Grazie mille per il tuo aiuto, ma non credo di aver condiviso abbastanza la situazione. item è un oggetto che viene creato caricamento della pagina. l'array di dimensioni degli oggetti entra nell'interazione dell'utente con un pulsante di modifica, quindi se lo faccio sovrascriverà l'intero oggetto. Ho bisogno di un modo per creare un gruppo di opzioni in una casella di selezione che preseleziona un valore da una parte completamente separata dell'oggetto dati.
Patrick,

14
È vero? Sembra che il gestore ng-change sia attivato prima dell'aggiornamento del modello ng, quindi provare $ scope.item.size.code = $ scope.selectedItem.code potrebbe non fornire sempre il valore del modello aggiornato. Qualcuno l'ha visto quando si utilizza ng-change?
Karl,

6
Suppongo che non ci sia nulla che ti impedisca di farlo:ng-model="selectedItem" ng-change="update(selectedItem)"
Rhys van der Waerden,

52

Puoi anche ottenere direttamente il valore selezionato usando il seguente codice

 <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
Questa risposta alla domanda mentre quella accettata fornisce un'alternativa
redben

1
dove inizializzi o ottieni la variabile template?
Kat Lim Ruiz,

29
Funziona senza specificare un modello? Ottengo questo errore: il controller 'ngModel', richiesto dalla direttiva 'select', non può essere trovato!
fer

8
ngModel è sicuramente necessario per selezionare elementi, secondo la documentazione. Le altre direttive sono opzionali, ma non lo è.
mnemia,

26
Questo non funziona! ng-change non ha accesso alla variabile temporanea (t) creata all'interno di ng-options.
Immondizia

16

puoi anche provare questo:

<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
Questa soluzione è valida se è necessario formattare il valore. Utilizzando solo l'approccio Select non sono riuscito a formattare facilmente il valore.
mbokil,

7

Se la risposta di Divyesh Rupawala non funziona (passando l'oggetto corrente come parametro), si prega di vedere la onChanged()funzione in questo Plunker. Sta usando this:

http://plnkr.co/edit/B5TDQJ


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

11
Usa ng-options invece di ng-repeat in una selezione.
Jepser Bernardino,

12
@JepserBernardino a volte è necessario un accesso più preciso a <option>, ad esempio per definire alcune opzioni speciali / predefinite indipendentemente dal fatto che siano selezionate o meno
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>

Se vuoi scrivere, nome, id, classe, multiplo, richiesto, puoi scrivere in questo modo.


1

Questo potrebbe darti alcune idee

Modello di visualizzazione .NET C #

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

Controller per API Web C # .NET

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

}

Controller angolare:

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

Dima angolare:

<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

È necessario utilizzare "traccia per" in modo che gli oggetti possano essere confrontati correttamente. Altrimenti Angular utilizzerà il modo js nativo di confrontare gli oggetti.

Quindi il tuo codice di esempio cambierebbe in -

    <select ng-options="size.code as size.name
 for size in sizes track by size.code" 
ng-model="item.size.code"></select>

1

Il filtro di AngularJS ha funzionato per me.

Supponendo che code/idsia unico , possiamo filtrare quel particolare oggetto con AngularJS filtere lavorare con le proprietà degli oggetti selezionati. Considerando l'esempio sopra:

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

Ora, ci sono 3 aspetti importanti in questo :

  1. ng-init="search.code = item.size.code"- sull'inizializzazione h1dell'elemento all'esterno della selectcasella, impostare la query del filtro sull'opzione selezionata .

  2. ng-change="update(MAGIC_THING); search.code = item.size.code"- quando modifichi l'ingresso selezionato, eseguiremo un'altra riga che imposterà la query di "ricerca" su quella attualmente selezionata item.size.code.

  3. filter:search:true- Passa trueal filtro per abilitare la corrispondenza rigorosa .

Questo è tutto. Se l' IDsize.code è uniqueID , avremo solo un h1elemento con il testo di size.name.

Ho provato questo nel mio progetto e funziona.

In bocca al lupo


0

Questo è il modo più pulito per ottenere un valore da un elenco di opzioni di selezione angolare (diverso da ID o testo). Supponendo di avere un prodotto Seleziona come questo sulla tua pagina:

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

Quindi nel controller impostare la funzione di richiamata in questo modo:

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

Spiegazione semplice: poiché l'evento ng-change non riconosce gli elementi di opzione nella selezione, stiamo usando ngModel per filtrare l'elemento selezionato dall'elenco di opzioni caricato nel controller.

Inoltre, poiché l'evento viene generato prima che ngModel sia realmente aggiornato, potresti ottenere risultati indesiderati, quindi un modo migliore sarebbe aggiungere un timeout:

        $scope.onSelectChange = function () {
            $timeout(function () {
            var filteredData = $scope.productsList.filter(function (response) {
                return response.Id === $scope.data.ProductId;
            })
            console.log(filteredData[0].ProductColor);
            }, 100);
        };
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.