Ottieni valore quando cambia l'opzione ng selezionata


114

Nella mia pagina .html ho un elenco a discesa,

Cadere in picchiata:

<select ng-model="blisterPackTemplateSelected" data-ng-options="blisterPackTemplate as blisterPackTemplate.name for blisterPackTemplate in blisterPackTemplates">
    <option value="">Select Account</option>
</select>

Voglio eseguire un'azione quando l'utente seleziona un valore. Quindi nel mio controller ho fatto:

controller:

$scope.$watch('blisterPackTemplateSelected', function() {
    alert('changed');
    console.log($scope.blisterPackTemplateSelected);
});

Ma la modifica del valore nell'elenco a discesa non attiva il codice: $scope.$watch('blisterPackTemplateSelected', function()

Di conseguenza ho provato un altro metodo con a: ng_change = 'changedValue()'sul tag select

e

Funzione:

$scope.changedValue = function() {
   console.log($scope.blisterPackTemplateSelected);
}

Ma blisterPackTemplateSelectedè archiviato in un ambito figlio. Ho letto che il genitore non può accedere all'ambito figlio.

Qual è il modo corretto / migliore per eseguire qualcosa quando un valore selezionato in un elenco a discesa cambia? Se è il metodo 1, cosa sto facendo di sbagliato con il mio codice?

Risposte:


187

come ha detto Artyom, devi usare ngChange e passare l'oggetto ngModel come argomento alla tua funzione ngChange

Esempio :

<div ng-app="App" >
  <div ng-controller="ctrl">
    <select ng-model="blisterPackTemplateSelected" ng-change="changedValue(blisterPackTemplateSelected)" 
            data-ng-options="blisterPackTemplate as blisterPackTemplate.name for blisterPackTemplate in blisterPackTemplates">
      <option value="">Select Account</option>
    </select>
    {{itemList}}     
  </div>       
</div>

js:

function ctrl($scope) {
  $scope.itemList = [];
  $scope.blisterPackTemplates = [{id:1,name:"a"},{id:2,name:"b"},{id:3,name:"c"}];

  $scope.changedValue = function(item) {
    $scope.itemList.push(item.name);
  }       
}

Esempio dal vivo: http://jsfiddle.net/choroshin/9w5XT/4/


ciao, ottima risposta. qui il valore dell'opzione impostato come dettagli dell'intera riga dell'articolo. come posso impostarlo su id?
AmiLinn

ciao @Alex Choroshin ho lo stesso tipo di problema ma ricevo dati dal database quando raccolgo dati dal database come mostrare quei dati in un div? provo questo nella funzione del controller $ scope.accountdetaildata = data.data; e in views div provo questo codice {{accountdetaildata .balance}} ma i dati non vengono visualizzati come dati ricevuti dal database e posso vedere quei dati nella console
Nadeem Ijaz

32

Potrei essere in ritardo per questo, ma ho avuto un po ' lo stesso problema.

Avevo bisogno di passare sia l'ID che il nome nel mio modello, ma tutte le soluzioni ortodosse mi hanno fatto creare il codice sul controller per gestire la modifica.

Sono riuscito a uscirne usando un filtro.

<select 
        ng-model="selected_id" 
        ng-options="o.id as o.name for o in options" 
        ng-change="selected_name=(options|filter:{id:selected_id})[0].name">
</select>
<script>
  angular.module("app",[])
  .controller("ctrl",['$scope',function($scope){
    $scope.options = [
      {id:1, name:'Starbuck'},
      {id:2, name:'Appolo'},
      {id:3, name:'Saul Tigh'},
      {id:4, name:'Adama'}
    ]
  }])
</script>

Il "trucco" è qui:

ng-change="selected_name=(options|filter:{id:selected_id})[0].name"

Sto usando il filtro integrato per recuperare il nome corretto per l'id

Ecco un plunkr con una demo funzionante.


20

Per favore, usa per esso la ngChangedirettiva. Per esempio:

<select ng-model="blisterPackTemplateSelected" 
        ng-options="blisterPackTemplate as blisterPackTemplate.name for blisterPackTemplate in blisterPackTemplates" 
        ng-change="changeValue(blisterPackTemplateSelected)"/>

E passa il valore del tuo nuovo modello nel controller come parametro:

ng-change="changeValue(blisterPackTemplateSelected)"

8

La migliore pratica è creare un oggetto (usa sempre a. In ng-model)

Nel tuo controller:

var myObj: {
     ngModelValue: null
};

e nel tuo modello:

<select 
    ng-model="myObj.ngModelValue" 
    ng-options="o.id as o.name for o in options">
</select>

Ora puoi solo guardare

myObj.ngModelValue

oppure puoi usare la direttiva ng-change in questo modo:

<select 
    ng-model="myObj.ngModelValue" 
    ng-options="o.id as o.name for o in options"
    ng-change="myChangeCallback()">
</select>

Il video egghead.io "The Dot" ha una panoramica davvero buona, così come questa domanda molto popolare sull'overflow dello stack: quali sono le sfumature dell'eredità prototipale / prototipica dell'ambito in AngularJS?


5

È possibile passare il valore ng-model tramite la funzione ng-change come parametro:

<select 
  ng-model="blisterPackTemplateSelected" 
  data-ng-options="blisterPackTemplate as blisterPackTemplate.name for blisterPackTemplate in blisterPackTemplates" 
  ng-change="changedValue(blisterPackTemplateSelected)">
    <option value="">Select Account</option>
</select>

È un po 'difficile conoscere il tuo scenario senza vederlo, ma dovrebbe funzionare.


2

Puoi fare qualcosa del genere

<html ng-app="App" >
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>

<script>
angular.module("App",[])
  .controller("ctrl",['$scope',function($scope){

    $scope.changedValue = function(item){       
    alert(item);
  }
  }]);
</script>
<div >
<div ng-controller="ctrl">
    <select  ng-model="blisterPackTemplateSelected" ng-change="changedValue(blisterPackTemplateSelected)" >
    <option value="">Select Account</option>
    <option value="Add">Add</option>
</select>
</div>
</div>
</html>

invece di aggiungere l'opzione dovresti usare data-ng-options. Ho usato l'opzione Aggiungi a scopo di test


2

Sono in ritardo qui ma ho risolto lo stesso tipo di problema in questo modo che è semplice e facile.

<select ng-model="blisterPackTemplateSelected" ng-change="selectedBlisterPack(blisterPackTemplateSelected)">
<option value="">Select Account</option>
<option ng-repeat="blisterPacks in blisterPackTemplates" value="{{blisterPacks.id}}">{{blisterPacks.name}}</option>

e la funzione per ng-change è la seguente;

 $scope.selectedBlisterPack= function (value) {  

        console.log($scope.blisterPackTemplateSelected);

    };

1

Otterrai il valore e il testo dell'opzione selezionata dall'elenco / matrice utilizzando il filtro.
editobj.FlagName = (employeeStatus | filtro: {Valore: editobj.Flag}) [0] .KeyName

<select name="statusSelect"
      id="statusSelect"
      class="form-control"
      ng-model="editobj.Flag"
      ng-options="option.Value as option.KeyName for option in EmployeeStatus"
      ng-change="editobj.FlagName=(EmployeeStatus|filter:{Value:editobj.Flag})[0].KeyName">
</select>

0

Ho avuto lo stesso problema e ho trovato una soluzione unica. Questa non è la migliore pratica, ma potrebbe rivelarsi semplice / utile per qualcuno. Basta usare jquery sull'ID o sulla classe o sul tag di selezione e avrai accesso sia al testo che al valore nella funzione di modifica. Nel mio caso sto passando i valori delle opzioni tramite sails / ejs:

    <select id="projectSelector" class="form-control" ng-model="ticket.project.id" ng-change="projectChange(ticket)">
      <% _.each(projects, function(project) { %>
        <option value="<%= project.id %>"><%= project.title %></option>
        <% }) %>
    </select>

Quindi nel mio controller Angular la mia funzione ng-change è simile a questa:

    $scope.projectChange = function($scope) {
         $scope.project.title=$("#projectSelector option:selected").text();
     };

0

Ho provato alcune soluzioni, ma ecco lo snippet di produzione di base. Per favore, presta attenzione all'output della console durante il controllo della qualità di questo frammento.

Mark Up:

<!DOCTYPE html>
<html ng-app="appUp">
<head>
<title>
  Angular Select snippet
</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/css/bootstrap.min.css" />

</head>


<body ng-controller="upController">

<div  class="container">

 <div class="row">
 <div class="col-md-4">

 </div> 
 <div class="col-md-3">
    <div class="form-group">
    <select name="slct" id="slct" class="form-control" ng-model="selBrand" ng-change="Changer(selBrand)" ng-options="brand as brand.name for brand in stock">
    <option value="">
        Select Brand
    </option>
    </select>
    </div>

    <div class="form-group">
    <input type="hidden" name="delimiter" value=":" ng-model="delimiter" />
    <input type="hidden" name="currency" value="$" ng-model="currency" />
    <span>
     {{selBrand.name}}{{delimiter}}{{selBrand.price}}{{currency}}
    </span>
    </div>

 </div> 
 <div class="col-md-4">

 </div>
 </div>
</div>

<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js">
</script>
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/tether/1.4.0/js/tether.min.js"></script>
<script src="//maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/js/bootstrap.min.js"></script>
<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.7/angular.min.js">
</script>
<script src="js/ui-bootstrap-tpls-2.5.0.min.js"></script>
<script src="js/main.js"></script>
</body>

</html>

Codice:

var c = console;

var d = document;


 var app = angular.module('appUp',[]).controller('upController',function($scope){

    $scope.stock = [{
     name:"Adidas",
     price:420      
    },
    {
     name:"Nike",
     price:327      
    },
    {
     name:"Clark",
     price:725      
    }
    ];//data 



    $scope.Changer = function(){
     if($scope.selBrand){ 
     c.log("brand:"+$scope.selBrand.name+",price:"+$scope.selBrand.price);
     $scope.currency = "$";
     $scope.delimiter = ":";
     }
     else{

        $scope.currency = "";
        $scope.delimiter = "";
        c.clear();
     }
    }; // onchange handler

 });

Spiegazione: il punto importante qui è il controllo nullo del valore modificato, cioè se il valore è 'undefined' o 'null' dovremmo gestire questa situazione.

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.