質問

I couldn't find an elegant way for setting null values with a <select> using 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};

When the page is loaded, the first option is selected, which is good, and the output is {"selected":null}. When that first option is reselected after having switch to another one, the output becomes {"selected":"null"} (with the quotes), which is not what I would expect.

Running example : http://plnkr.co/edit/WuJrBBGuHGqbKq6yL4La

I know that the markup <option value=null> is not correct. I also tried with <option value=""> but it corresponds to an empty String and not to null : the first option is therefore not selected and another option which disappears after the first selection is selected by default.

Any idea ?

役に立ちましたか?

解決

This should work for you:

Controller:

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

Template:

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

Working plnkr

You should use ng-options with select.

他のヒント

You can use the ngOptions directive on the select. According to the documentation:

Optionally, a single hard-coded <option> element, with the value set to an empty string, can be nested into the <select> element. This element will then represent the null or "not selected" option. See example below for demonstration.

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

It's obviously a better idea to define the options list directly in the controller.

Try using ng-options instead of manually creating tags, as in this example, lightly-edited from the Angular docs:

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

The operative parts here are lines 17, defining a 'colors' object, and the ng-options attributes iterating over those colors to create options.

If you REALLY want to use null, see below. You need to use ng-options and let Angular handle the mapping:

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

I ran into the same Problem but could not solve it via 'ng-options'. My solution is:

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

You can use it like this:

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

Can you try to use parseInt on the value? For example, both "1" and "0" will equal their respective integer values. If you run the empty string through parseInt you can easily get NaN.

> parseInt("") = NaN

> parseInt("0") === 0

> parseInt("1") === 1

Without the possibility of using ng-options I present another fix.

I've been battling this a couple of months now, using solutions presented on this question and I don't know how nobody posted this:

<option value="null"></option>

This should work on Angular 1.6 and above for sure when you are using ng-repeat for options instead of ng-options.

It's not ideal but since we are used to work on legacy code this simple fix could save your day.

the only way you can achieve that is by using a onchange event and restoring the object as initialized any other attempt to set the selected to null will remove the property from the object.

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

this is a bad idea, you should always have values in your model instead of playing around with null and undefined

This is much easier on Angular2/Angular where you can just use

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

This value is no longer a string, but a real null value.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top