Obtener valor cuando cambia la opción ng seleccionada

114

Tengo en mi página .html una lista desplegable,

Desplegable:

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

Quiero ejecutar una acción cuando el usuario seleccione un valor. Entonces en mi controlador hice:

Controlador:

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

Pero cambiar el valor en la lista desplegable no activa el código: $scope.$watch('blisterPackTemplateSelected', function()

Como resultado, probé otro método con: ng_change = 'changedValue()'en la etiqueta de selección

y

Función:

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

Pero blisterPackTemplateSelectedse almacena en un ámbito secundario. Leí que el padre no puede acceder al alcance del niño.

¿Cuál es la forma correcta / mejor de ejecutar algo cuando cambia un valor seleccionado en una lista desplegable? Si es el método 1, ¿qué estoy haciendo mal con mi código?

xiaolong97427
fuente

Respuestas:

187

como dijo Artyom, debe usar ngChange y pasar el objeto ngModel como argumento a su función ngChange

Ejemplo :

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

Ejemplo en vivo: http://jsfiddle.net/choroshin/9w5XT/4/

Alex Choroshin
fuente
hola, gran respuesta. aquí el valor de la opción se establece como detalles de fila completa del artículo. ¿Cómo puedo configurarlo en id?
AmiLinn
hola @ Alex Choroshin tengo el mismo tipo de problema, pero obtengo datos de la base de datos cuando recopilo datos de la base de datos, ¿cómo mostrar esos datos en un div? Intento esto en la función del controlador $ scope.accountdetaildata = data.data; y en las vistas div pruebo este código {{accountdetaildata .balance}} pero los datos no se muestran allí como datos recibidos de la base de datos y puedo ver esos datos en la consola
Nadeem Ijaz
32

Puede que sea tarde para esto, pero yo tenía un poco el mismo problema.

Necesitaba pasar tanto la identificación como el nombre en mi modelo, pero todas las soluciones ortodoxas me hicieron hacer un código en el controlador para manejar el cambio.

Me abrí camino con 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>

El "truco" está aquí:

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

Estoy usando el filtro incorporado para recuperar el nombre correcto de la identificación

Aquí hay un plunkr con una demostración funcional.

Simón
fuente
20

Por favor, use la ngChangedirectiva for it . Por ejemplo:

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

Y pase el valor de su nuevo modelo en el controlador como parámetro:

ng-change="changeValue(blisterPackTemplateSelected)"
Artyom Pranovich
fuente
8

La mejor práctica es crear un objeto (siempre use a. In ng-model)

En tu controlador:

var myObj: {
     ngModelValue: null
};

y en tu plantilla:

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

Ahora solo puedes mirar

myObj.ngModelValue

o puede usar la directiva ng-change así:

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

El video de egghead.io "The Dot" tiene una muy buena descripción, al igual que esta muy popular pregunta de desbordamiento de pila: ¿Cuáles son los matices de la herencia prototípica / prototípica de alcance en AngularJS?

Martijn Welker
fuente
5

Puede pasar el valor del modelo ng a través de la función ng-change como parámetro:

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

Es un poco difícil conocer su escenario sin verlo, pero esto debería funcionar.

Wawy
fuente
2

Puedes hacer algo como esto

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

en lugar de agregar la opción, debe usar data-ng-options. He usado la opción Agregar para fines de prueba

Saurabh
fuente
2

Llego tarde aquí, pero resolví el mismo tipo de problema de esta manera que es simple y fácil.

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

y la función para ng-change es la siguiente;

 $scope.selectedBlisterPack= function (value) {  

        console.log($scope.blisterPackTemplateSelected);

    };
Usman
fuente
1

Obtendrá el valor y el texto de la opción seleccionada de la lista / matriz utilizando el filtro.
editobj.FlagName = (EmployeeStatus | filtro: {Valor: 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>
Rahul Modi
fuente
0

Tuve el mismo problema y encontré una solución única. Esta no es la mejor práctica, pero puede resultar simple / útil para alguien. Simplemente use jquery en la identificación o clase o su etiqueta de selección y luego tendrá acceso tanto al texto como al valor en la función de cambio. En mi caso, estoy pasando valores de opción a través de 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>

Luego, en mi controlador Angular, mi función ng-change se ve así:

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

He probado algunas soluciones, pero aquí hay un fragmento de producción básico. Preste atención a la salida de la consola durante el control de calidad de este fragmento.

Margen :

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

Código:

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

 });

Explicación: el punto importante aquí es la verificación nula del valor cambiado, es decir, si el valor es 'indefinido' o 'nulo' deberíamos manejar esta situación.

Kirill Shur
fuente