AngularJS valeur null pour select

Je n'ai pas trouvé de moyen élégant de définir des valeurs null avec un <select> en utilisant AngularJS.

HTML:

<select ng-model="obj.selected">
  <option value=null>Unknown</option>
  <option value="1">Yes</option>
  <option value="0">No</option>
</select>

{{obj}}

JS:

$scope.obj ={"selected":null};

Lorsque la page est chargée, la première option est sélectionnée, ce qui est bon, et la sortie est de {"selected":null}. Lorsque cette première option est resélectionnée après avoir passé à une autre, la sortie devient {"selected":"null"} (avec les guillemets), ce qui n'est pas ce à quoi je m'attendais.

Exemple en cours D'exécution : http://plnkr.co/edit/WuJrBBGuHGqbKq6yL4La

Je sais que le balisage <option value=null> n'est pas correct. J'ai aussi essayé avec <option value=""> mais cela correspond à une chaîne vide et non à null: la première option n'est donc pas sélectionnée et une autre option qui disparaît après la première sélection est sélectionnée par défaut.

Une idée ?

32
demandé sur Juljan 2014-05-15 22:34:27

8 réponses

Cela devrait fonctionner pour vous:

Contrôleur:

  function MyCntrl($scope) {
    $scope.obj ={"selected":null};
    $scope.objects = [{id: 1, value: "Yes"}, {id: 0, value: "No"}]
  }

Modèle:

  <div ng-controller="MyCntrl">

    <select ng-model="obj.selected"
            ng-options="value.id as value.value for value in objects">
            <option value="">Unknown</option>
    </select>

<br/>
     {{obj}}
  </div>

Plnkr de travail

Vous devez utiliser ng-options à sélectionner.

34
répondu Wawy 2014-05-15 18:48:57

Vous pouvez utiliser le ngOptions la directive sur la select. Selon la documentation:

En option, un seul élément <option> codé en dur, avec la valeur définie sur une chaîne vide, peut être imbriqué dans l'élément <select>. Cet élément représentera alors l'option null ou "non sélectionné". Voir l'exemple ci-dessous pour la démonstration.

<select ng-model="obj.selected" ng-options="key as label for (key, label) in ['No', 'Yes']">
  <option value="">Unknown</option>
</select>

, Il est évidemment préférable de définir la liste des options directement dans le contrôleur.

17
répondu Blackhole 2014-05-15 18:47:58

Essayez d'utiliser ng-options au lieu de créer manuellement des balises, comme dans cet exemple, légèrement éditées à partir des documents angulaires:

Http://plnkr.co/edit/DVXwlFR6MfcfYPNHScO5?p=preview

Les parties opératoires ici sont les lignes 17, définissant un objet' colors', et les attributs ng-options itèrent sur ces couleurs pour créer des options.

3
répondu chrispittman 2014-05-15 18:47:39

Si vous voulez vraiment utiliser null, voir ci-dessous. Vous devez utiliser ng-options et laisser Angular gérer le mappage:

<!doctype html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Color selector</title>

  <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.0-beta.8/angular.min.js"></script>

</head>
<body ng-app="">
    <script>
  function MyCntrl($scope) {
    $scope.obj ={"selected":null};
    $scope.objStates = [{key:"Unknown", value:null}, {key:"Yes", value:1}, {key:"No", value:0}]

    $scope.$watch('obj.selected', function(newVal){
      console.log(newVal);
    })
  }
  </script>
  <div ng-controller="MyCntrl">

    <select ng-model="obj.selected" ng-options="state.value as state.key for state in objStates">
    </select>

<br/>
     {{obj}}
  </div>
</body>
</html>
2
répondu Andrew Church 2014-05-15 18:50:42

J'ai rencontré le MÊME PROBLÈME MAIS je n'ai pas pu le résoudre via 'ng-options'. Ma solution est:

module.directive('modelToNull', [function () {
    return {
        scope: {
            check: "&modelToNull"
        },
        require: 'ngModel',
        link: function ($scope, element, attrs, ngModelController) {
            ngModelController.$parsers.push(function (value) {
                return value == null || $scope.check({value: value}) ? null : value;
            });
        }
    };
}]);

Vous pouvez l'utiliser comme ceci:

<select ng-model="obj.selected" model-to-null="value == 'null'">
  <option value="null">Unknown</option>
  <option value="1">Yes</option>
  <option value="0">No</option>
</select>
2
répondu Robert.MD 2016-09-02 09:03:47

Pouvez-vous essayer d'utiliser parseInt sur la valeur? Par exemple, "1" et "0" seront égaux à leurs valeurs entières respectives. Si vous exécutez la chaîne vide par parseInt, vous pouvez facilement obtenir NaN.

> parseInt("") = NaN

> parseInt("0") === 0

> parseInt("1") === 1
0
répondu Ishan Chatterjee 2014-05-15 18:43:22

C'est beaucoup plus facile sur Angular2/Angulaire où vous pouvez simplement utiliser

<option [value]="null">Unknown</option>

Cette valeur n'est plus une chaîne, mais une valeur nulle réelle.

0
répondu MEhran 2017-06-30 14:01:59

La seule façon d'y parvenir est d'utiliser un événement onchange et de restaurer l'objet comme initialisé toute autre tentative de définir la valeur NULL sélectionnée supprimera la propriété de l'objet.

$scope.setValue=function(val){
  if($scope.obj.selected=="null")
     $scope.obj ={"selected":null};
}

<select ng-change="setValue()" ng-model="obj.selected">
  <option value=null ng-click="obj.selected=null">Unknown</option>
  <option value="1">Yes</option>
  <option value="0">No</option>
</select>

C'est une mauvaise idée, vous devriez toujours avoir des valeurs dans votre modèle au lieu de jouer avec null et undefined

-1
répondu Dayan Moreno Leon 2014-05-15 19:00:42