Question Travailler avec select en utilisant les options ng d'AngularJS


J'ai lu à ce sujet dans d'autres articles, mais je ne pouvais pas le comprendre.

J'ai un tableau,

$scope.items = [
   {ID: '000001', Title: 'Chicago'},
   {ID: '000002', Title: 'New York'},
   {ID: '000003', Title: 'Washington'},
];

Je veux le rendre comme:

<select>
  <option value="000001">Chicago</option>
  <option value="000002">New York</option>
  <option value="000003">Washington</option>
</select>

Et aussi je veux sélectionner l'option avec ID = 000002.

J'ai lu sélectionner et essayé, mais je ne peux pas le comprendre.


421
2017-10-24 11:03


origine


Réponses:


Une chose à noter est que ngModel est Champs obligatoires pour que ngOptions fonctionne ... notez le ng-model="blah" qui dit "mettre $ scope.blah à la valeur sélectionnée".

Essaye ça:

<select ng-model="blah" ng-options="item.ID as item.Title for item in items"></select>

Voici plus de la documentation de AngularJS (si vous ne l'avez pas vu):

pour les sources de données de tableau:

  • label pour valeur dans tableau
  • sélectionnez comme étiquette pour la valeur dans le tableau
  • label groupe par groupe pour la valeur dans le tableau   = sélectionner comme groupe d'étiquettes par groupe pour la valeur dans le tableau

pour les sources de données d'objet:

  • étiquette pour (clé, valeur) dans l'objet
  • sélectionner comme étiquette pour (clé, valeur) dans l'objet
  • label groupe par groupe pour (clé, valeur) dans objet
  • sélectionner comme label groupe par groupe pour (clé, valeur) dans l'objet

Pour des éclaircissements sur les valeurs des balises d'option dans AngularJS:

Lorsque vous utilisez ng-options, les valeurs des balises d'option écrites par ng-options seront toujours l'index de l'élément de tableau associé à la balise d'option. C'est parce que AngularJS vous permet réellement de sélectionner des objets entiers avec des contrôles sélectionnés, et pas seulement des types primitifs. Par exemple:

app.controller('MainCtrl', function($scope) {
   $scope.items = [
     { id: 1, name: 'foo' },
     { id: 2, name: 'bar' },
     { id: 3, name: 'blah' }
   ];
});
<div ng-controller="MainCtrl">
   <select ng-model="selectedItem" ng-options="item as item.name for item in items"></select>
   <pre>{{selectedItem | json}}</pre>
</div>

Ce qui précède vous permettra de sélectionner un objet entier dans $scope.selectedItem directement. Le point est, avec AngularJS, vous n'avez pas besoin de vous soucier de ce que contient votre option tag. Laissez AngularJS gérer cela; vous ne devriez vous soucier que de ce que contient votre modèle dans votre champ d’application.

Voici un plunker démontrant le comportement ci-dessus, et montrant le code HTML écrit


Traiter avec l'option par défaut:

Il y a quelques choses que je n'ai pas mentionné ci-dessus concernant l'option par défaut.

Sélection de la première option et suppression de l’option vide:

Vous pouvez le faire en ajoutant un simple ng-init qui définit le modèle (à partir de ng-model) au premier élément des éléments que vous répétez ng-options:

<select ng-init="foo = foo || items[0]" ng-model="foo" ng-options="item as item.name for item in items"></select>

Note: Cela pourrait devenir un peu fou si foo arrive à être initialisé correctement à quelque chose de "falsifié". Dans ce cas, vous devrez gérer l'initialisation de foo dans votre contrôleur, très probablement.

Personnalisation de l'option par défaut:

C'est un peu différent; ici tout ce que vous devez faire est d'ajouter une balise d'option en tant qu'enfant de votre select, avec un attribut de valeur vide, puis personnaliser son texte interne:

<select ng-model="foo" ng-options="item as item.name for item in items">
   <option value="">Nothing selected</option>
</select>

Note: Dans ce cas, l'option "vide" restera là même après avoir sélectionné une autre option. Ce n'est pas le cas pour le comportement par défaut des sélections sous AngularJS.

Une option par défaut personnalisée qui se cache après la sélection:

Si vous souhaitez que votre option par défaut personnalisée disparaisse après avoir sélectionné une valeur, vous pouvez ajouter un attribut ng-hide à votre option par défaut:

<select ng-model="foo" ng-options="item as item.name for item in items">
   <option value="" ng-if="foo">Select something to remove me.</option>
</select>

770
2017-10-24 12:59



J'apprends AngularJS et je me débattais avec la sélection. Je sais que cette question a déjà répondu, mais je voulais quand même partager un peu plus de code.

Dans mon test, j'ai deux listboxes: marques et modèles de voitures. La liste des modèles est désactivée jusqu'à ce que make soit sélectionné. Si la sélection dans la liste des marques est réinitialisée ultérieurement (définie sur «Sélectionner la marque»), la liste des modèles est à nouveau désactivée ET sa sélection est également réinitialisée (sur «Sélectionner un modèle»). Les marques sont récupérées en tant que ressource alors que les modèles sont simplement codés en dur.

Rend JSON:

[
{"code": "0", "name": "Select Make"},
{"code": "1", "name": "Acura"},
{"code": "2", "name": "Audi"}
]

services.js:

angular.module('makeServices', ['ngResource']).
factory('Make', function($resource){
    return $resource('makes.json', {}, {
        query: {method:'GET', isArray:true}
    });
});

Fichier HTML:

<div ng:controller="MakeModelCtrl">
  <div>Make</div>
  <select id="makeListBox"
      ng-model="make.selected"
      ng-options="make.code as make.name for make in makes"
      ng-change="makeChanged(make.selected)">
  </select>

  <div>Model</div>
  <select id="modelListBox"
     ng-disabled="makeNotSelected"
     ng-model="model.selected"
     ng-options="model.code as model.name for model in models">
  </select>
</div>

controllers.js:

function MakeModelCtrl($scope)
{
    $scope.makeNotSelected = true;
    $scope.make = {selected: "0"};
    $scope.makes = Make.query({}, function (makes) {
         $scope.make = {selected: makes[0].code};
    });

    $scope.makeChanged = function(selectedMakeCode) {
        $scope.makeNotSelected = !selectedMakeCode;
        if ($scope.makeNotSelected)
        {
            $scope.model = {selected: "0"};
        }
    };

    $scope.models = [
      {code:"0", name:"Select Model"},
      {code:"1", name:"Model1"},
      {code:"2", name:"Model2"}
    ];
    $scope.model = {selected: "0"};
}

87
2017-11-27 20:52



Pour une raison quelconque, AngularJS permet de me confondre. Leur documentation est assez horrible à ce sujet. Plus de bons exemples de variations seraient les bienvenus.

Quoi qu’il en soit, j’ai une légère variation sur la réponse de Ben Lesh.

Mes collections de données ressemblent à ceci:

items =
[
   { key:"AD",value:"Andorra" }
,  { key:"AI",value:"Anguilla" }
,  { key:"AO",value:"Angola" }
 ...etc..
]

À présent

<select ng-model="countries" ng-options="item.key as item.value for item in items"></select>

la valeur des options était toujours l'indice (0, 1, 2, etc.).

Ajouter Suivre par l'a fixé pour moi:

<select ng-model="blah" ng-options="item.value for item in items track by item.key"></select>

Je pense qu'il arrive plus souvent que vous vouliez ajouter un tableau d'objets dans une liste de sélection, alors je vais me souvenir de celui-ci!

Sachez que depuis AngularJS 1.4, vous ne pouvez plus utiliser ng-options, mais vous devez utiliser ng-repeat sur votre tag d'option:

<select name="test">
   <option ng-repeat="item in items" value="{{item.key}}">{{item.value}}</option>
</select>

35
2017-10-26 07:21



La question est déjà répondue (BTW, réponse vraiment bonne et complète fournie par Ben), mais je voudrais ajouter un autre élément pour l'exhaustivité, qui peut être aussi très pratique.

Dans l'exemple suggéré par Ben:

<select ng-model="blah" ng-options="item.ID as item.Title for item in items"></select>

le suivant ngOptions formulaire a été utilisé: select as label for value in array.

Étiquette est une expression, dont le résultat sera l'étiquette pour <option> élément. Dans ce cas, vous pouvez effectuer certaines concaténations de chaînes, afin d'avoir des étiquettes d'options plus complexes.

Exemples:

  • ng-options="item.ID as item.Title + ' - ' + item.ID for item in items" vous donne des étiquettes comme Title - ID
  • ng-options="item.ID as item.Title + ' (' + item.Title.length + ')' for item in items" vous donne des étiquettes comme Title (X), où X est la longueur de la chaîne de titre.

Vous pouvez également utiliser des filtres, par exemple,

  • ng-options="item.ID as item.Title + ' (' + (item.Title | uppercase) + ')' for item in items" vous donne des étiquettes comme Title (TITLE), où la valeur Title de la propriété Title et TITLE est la même valeur mais convertie en caractères majuscules.
  • ng-options="item.ID as item.Title + ' (' + (item.SomeDate | date) + ')' for item in items" vous donne des étiquettes comme Title (27 Sep 2015), si votre modèle a une propriété SomeDate

15
2017-09-28 10:59



Dans CoffeeScript:

#directive
app.directive('select2', ->
    templateUrl: 'partials/select.html'
    restrict: 'E'
    transclude: 1
    replace: 1
    scope:
        options: '='
        model: '='
    link: (scope, el, atr)->
        el.bind 'change', ->
            console.log this.value
            scope.model = parseInt(this.value)
            console.log scope
            scope.$apply()
)
<!-- HTML partial -->
<select>
  <option ng-repeat='o in options'
          value='{{$index}}' ng-bind='o'></option>
</select>

<!-- HTML usage -->
<select2 options='mnuOffline' model='offlinePage.toggle' ></select2>

<!-- Conclusion -->
<p>Sometimes it's much easier to create your own directive...</p>

7
2017-09-06 05:51



Si vous avez besoin d'un titre personnalisé pour chaque option, ng-options n'est pas applicable. Au lieu d'utiliser ng-repeat avec des options:

<select ng-model="myVariable">
  <option ng-repeat="item in items"
          value="{{item.ID}}"
          title="Custom title: {{item.Title}} [{{item.ID}}]">
       {{item.Title}}
  </option>
</select>

5
2017-07-13 21:08



J'espère que ce qui suit travaillera pour vous.

<select class="form-control"
        ng-model="selectedOption"
        ng-options="option.name + ' (' + (option.price | currency:'USD$') + ')' for option in options">
</select>

3
2017-10-10 08:40