Obter valor quando as opções de ng selecionadas forem alteradas


114

Tenho em minha página .html uma lista suspensa,

Suspenso:

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

Quero executar uma ação quando o usuário seleciona um valor. Então, no meu controlador eu fiz:

Controlador:

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

Mas a alteração do valor na lista suspensa não aciona o código: $scope.$watch('blisterPackTemplateSelected', function()

Como resultado, tentei outro método com um: ng_change = 'changedValue()'na tag select

e

Função:

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

Mas o blisterPackTemplateSelectedé armazenado em um escopo filho. Eu li que o pai não pode obter acesso ao escopo filho.

Qual é a maneira correta / melhor de executar algo quando um valor selecionado em uma lista suspensa muda? Se for o método 1, o que estou fazendo de errado com meu código?

Respostas:


187

como Artyom disse, você precisa usar ngChange e passar o objeto ngModel como argumento para sua função ngChange

Exemplo :

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

Exemplo ao vivo: http://jsfiddle.net/choroshin/9w5XT/4/


oi, ótima resposta. aqui o valor da opção definido como detalhes de linha inteira do item. como posso configurá-lo para id?
AmiLinn

oi @Alex Choroshin eu tenho o mesmo tipo de problema, mas estou recebendo dados do banco de dados quando eu coleto dados do banco de dados. Como mostrar esses dados em um div? eu tento fazer isso na função do controlador $ scope.accountdetaildata = data.data; e em views div, tento este código {{accountdetaildata .balance}}, mas os dados não são mostrados lá como dados recebidos do banco de dados e posso ver esses dados no console
Nadeem Ijaz

32

I pode ser tarde para isso, mas eu tinha um pouco o mesmo problema.

Eu precisava passar o id e o nome para o meu modelo, mas todas as soluções ortodoxas me fizeram criar um código no controlador para lidar com a mudança.

Eu consegui sair dele usando um 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>

O "truque" está aqui:

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

Estou usando o filtro embutido para recuperar o nome correto para o id

Aqui está um plunkr com uma demonstração de trabalho.


20

Por favor, use para esta ngChangediretiva. Por exemplo:

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

E passe seu novo valor de modelo no controlador como um parâmetro:

ng-change="changeValue(blisterPackTemplateSelected)"

8

A melhor prática é criar um objeto (sempre use um. Em ng-model)

Em seu controlador:

var myObj: {
     ngModelValue: null
};

e em seu modelo:

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

Agora você pode apenas assistir

myObj.ngModelValue

ou você pode usar a diretiva ng-change assim:

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

O vídeo egghead.io "The Dot" tem uma visão geral realmente boa, assim como esta pergunta de estouro de pilha muito popular: Quais são as nuances da herança prototípica / prototípica do escopo no AngularJS?


5

Você pode passar o valor do modelo ng por meio da função ng-change como um 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>

É um pouco difícil saber seu cenário sem vê-lo, mas isso deve funcionar.


2

Você pode fazer algo assim

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

em vez de adicionar a opção, você deve usar data-ng-options. Usei a opção Adicionar para fins de teste


2

Estou atrasado aqui, mas resolvi o mesmo tipo de problema desta forma que é simples e 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>

e a função para mudança de ng é a seguinte;

 $scope.selectedBlisterPack= function (value) {  

        console.log($scope.blisterPackTemplateSelected);

    };

1

Você obterá o valor e o texto da opção selecionada da lista / matriz usando o filtro.
editobj.FlagName = (EmployeeStatus | filtro: {Value: 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

Eu tive o mesmo problema e encontrei uma solução única. Esta não é a melhor prática, mas pode ser simples / útil para alguém. Basta usar jquery no id ou classe ou em sua tag select e você terá acesso ao texto e ao valor na função de alteração. No meu caso, estou passando valores de opções via 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>

Então, no meu controlador Angular, minha função de mudança de ng é assim:

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

0

Eu tentei algumas soluções, mas aqui está um trecho de produção básico. Por favor, preste atenção à saída do console durante a garantia de qualidade deste trecho.

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>

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

 });

Explicação: o ponto importante aqui é a verificação de nulo do valor alterado, ou seja, se o valor for 'indefinido' ou 'nulo', devemos lidar com esta situação.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.