obtenir l'objet ng sélectionné avec ng-change

313

Étant donné l'élément de sélection suivant

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

Existe-t-il un moyen d'obtenir MAGIC_THING égal à la taille actuellement sélectionnée, j'ai donc accès à size.nameet size.codedans mon contrôleur?

size.code affecte de nombreuses autres parties de l'application (URL d'image, etc.), mais lorsque le modèle ng de item.size.codeest mis à jour, il item.size.namedoit également être mis à jour pour les utilisateurs. Je suppose que la bonne façon de procéder consiste à capturer l'événement de modification et à définir les valeurs à l'intérieur de mon contrôleur, mais je ne suis pas sûr de ce que je peux passer à la mise à jour pour obtenir les valeurs appropriées.

Si c'est complètement la mauvaise façon de procéder, j'aimerais savoir la bonne façon.

Patrick
la source

Réponses:

488

Au lieu de définir le ng-model sur item.size.code, que diriez-vous de le définir à la taille:

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

Ensuite, dans votre update()méthode, $scope.itemsera défini sur l'élément actuellement sélectionné.

Et quel que soit le code nécessaire item.size.code, vous pouvez obtenir cette propriété via $scope.item.code.

Violon .

Mise à jour basée sur plus d'informations dans les commentaires:

Utilisez une autre propriété $ scope pour votre modèle ng sélectionné, puis:

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

Manette:

$scope.update = function() {
   $scope.item.size.code = $scope.selectedItem.code
   // use $scope.selectedItem.code and $scope.selectedItem.name here
   // for other stuff ...
}
Mark Rajcok
la source
1
Si je définis mon modèle comme article, comment présélectionner une valeur?
Patrick
5
Mettez ceci dans votre <select>: ng-init = "item = tailles [0]"
Mark Rajcok
Merci beaucoup pour votre aide, mais je ne pense pas avoir suffisamment partagé la situation. l'élément est un objet qui est créé un chargement de page. le tableau des tailles d'objets entre en interaction avec l'utilisateur avec un bouton d'édition, donc si je fais cela, il remplacera l'objet objet entier. J'ai besoin d'un moyen de créer un tas d'options dans une zone de sélection qui présélectionne une valeur à partir d'une partie complètement distincte de l'objet de données.
Patrick
14
Est-ce vrai? Il semble que le gestionnaire ng-change soit déclenché avant la mise à jour du modèle ng, donc essayer $ scope.item.size.code = $ scope.selectedItem.code peut ne pas toujours vous donner la valeur de modèle mise à jour. Quelqu'un a-t-il vu cela lors de l'utilisation de ng-change?
Karl
6
Je suppose que rien ne vous empêche de faire cela non plus:ng-model="selectedItem" ng-change="update(selectedItem)"
Rhys van der Waerden
52

Vous pouvez également obtenir directement la valeur sélectionnée en utilisant le code suivant

 <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);
}
Divyesh Rupawala
la source
5
Cela répond à la question tandis que l'accepté donne une alternative
redben
1
où initialisez-vous ou obtenez-vous la variable de modèle?
Kat Lim Ruiz
29
Est-ce que cela fonctionne sans spécifier de modèle? J'obtiens cette erreur: le contrôleur 'ngModel', requis par la directive 'select', est introuvable!
fer
8
ngModel est définitivement requis pour certains éléments, selon la documentation. Les autres directives sont facultatives, mais celle-là ne l'est pas.
mnémie
26
Cela ne fonctionne pas! ng-change n'a pas accès à la variable temporaire (t) créée à l'intérieur de ng-options.
Garbage
16

vous pouvez aussi essayer ceci:

<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>
DolceVita
la source
2
Cette solution est bonne si vous devez formater la valeur. En utilisant uniquement l'approche Select, je n'ai pas pu formater la valeur facilement.
mbokil
7

Si la réponse de Divyesh Rupawala ne fonctionne pas (en passant l'élément actuel comme paramètre), veuillez voir la onChanged()fonction dans ce Plunker. Il utilise this:

http://plnkr.co/edit/B5TDQJ

abbaf33f
la source
2
<select ng-model="item.size.code">
<option ng-repeat="size in sizes" ng-attr-value="size.code">{{size.name}}          </option>
</select>
Jignesh Variya
la source
11
Utilisez ng-options au lieu de ng-repeat dans une sélection.
Jepser Bernardino
12
@JepserBernardino vous avez parfois besoin d'un accès plus fin à <option>, par exemple pour styliser certaines options spéciales / par défaut, qu'elles soient sélectionnées ou non
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>

Si vous voulez écrire, nom, id, classe, multiple, requis, vous pouvez écrire de cette façon.

barış çıracı
la source
1

Cela pourrait vous donner quelques idées

.NET C # Voir le modèle

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

Contrôleur Web Api .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);
    }

}

Contrôleur angulaire:

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

Modèle angulaire:

<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>
meffect
la source
1

Vous devez utiliser "track by" afin que les objets puissent être comparés correctement. Sinon, Angular utilisera la façon native js de comparer les objets.

Donc, votre exemple de code se changerait en -

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

Le filtre d'AngularJS a fonctionné pour moi.

En supposant que le code/idest unique , nous pouvons filtrer cet objet particulier avec AngularJSfilter et travailler avec les propriétés des objets sélectionnés. Considérant l'exemple ci-dessus:

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

Maintenant, il y a 3 aspects importants à cela :

  1. ng-init="search.code = item.size.code"- lors de l'initialisation de l' h1élément en dehors de la selectboîte, définissez la requête de filtre sur l' option sélectionnée .

  2. ng-change="update(MAGIC_THING); search.code = item.size.code" - lorsque vous modifiez l'entrée de sélection, nous exécutons une ligne de plus qui définira la requête "recherche" sur la sélection actuellement sélectionnée item.size.code .

  3. filter:search:true- Passez trueau filtre pour permettre une correspondance stricte .

C'est tout. Si l' IDsize.code est unique , nous n'en aurons qu'unh1 élément avec le texte de size.name.

J'ai testé cela dans mon projet et cela fonctionne.

Bonne chance

Akash
la source
0

C'est le moyen le plus propre d'obtenir une valeur à partir d'une liste d'options de sélection angulaire (autre que l'ID ou le texte). En supposant que vous ayez un produit sélectionné comme celui-ci sur votre page:

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

Ensuite, dans votre contrôleur, définissez la fonction de rappel comme suit:

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

Expliqué simplement: donné que l'événement ng-change ne reconnaît pas les éléments d'option dans la sélection, nous utilisons ngModel pour filtrer l'élément sélectionné de la liste d'options chargée dans le contrôleur.

De plus, puisque l'événement est déclenché avant que le ngModel ne soit vraiment mis à jour, vous pourriez obtenir des résultats indésirables, donc une meilleure façon serait d'ajouter un délai d'attente:

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