简体   繁体   中英

Angular, boolean value in a select box

I want to set a boolean value to true or false using a select here is my code:

<select class="span9" ng-model="proposal.formalStoryboard">
<option value="false">Not Included</option>
<option value="true">Included</option>
</select>

The value (proposal.formalStoryboard) is set properly to true or false but the change are not reflected on the select box when the value is already assigned.

I tried ng-value="true" and ng-value="false" instead of just value but it's not working as well.

EDIT: Commentors have pointed out that my original solution did not work as claimed. I have updated the answer to reflect the correct answer given by others below (I cannot delete an accepted answer).

For Angular 1.0.6, consider this HTML:

<div ng-app="">
  <div ng-controller="MyCntrl">
    <select ng-model="mybool"
            ng-options="o.v as o.n for o in [{ n: 'Not included', v: false }, { n: 'Included', v: true }]">
    </select>
    <p>
        Currently selected: <b>{{ mybool }}</b> opposite: {{ !mybool }}
   </p> 
 </div>
</div>

And this JavaScript:

function MyCntrl($scope) {
    $scope.mybool = true;
}

Here is a working DEMO for Angular 1.0.6 and here is a working DEMO for Angular 1.3.14, which is slightly different.

Just do like this:

<select ng-model="someModel" ng-options="boolToStr(item) for item in [true, false]">
</select>

and define:

$scope.boolToStr = function(arg) {return arg ? 'Included' : 'Not included'};

为什么不直接使用这个?

<select class="form-control" ng-options="(item?'Included':'Not Included') for item in [true, false]"></select>

If you are using angularjs version >= 1.2.0 you will have access to the directive ng-value

You can use the ng-value on an option element. Your htmls would work like this.

<select ng-model="proposal.formalStoryboard">
    <option ng-value="true">Included</option>
    <option ng-value="false">Not Included</option>
</select>

It also works on radio and checkboxes.

I would recommend using a directive for this. As usual, I try to stay away from timeouts and other async operations in preference of a more authoritative and direct control.

directives.directive('boolean', function() {
  return {
    priority: '50',
    require: 'ngModel',
    link: function(_, __, ___, ngModel) {
      ngModel.$parsers.push(function(value) {
        return value == 'true' || value == true;
      });

      ngModel.$formatters.push(function(value) {
        return value && value != 'false' ? 'true' : 'false';
      });
    }
  };
});

The priority is set specifically so that it is done prior to any other directives (that usually don't have a priority set, and defaults to 0 )

For example, I use this directive (for a true/false selection) with my selectpicker directive that wraps my select elements in the selectpicker bootstrap plugin.

Edit:

The caveat here, which I forgot to mention, is that your html values need to be string values. What the directive does is translates between the view and the model, keeping the model value in boolean and your view in string format:

%select.selectpicker{ ng: { model: 'modelForm.listed' }, selectpicker: '{ }', boolean: true }
  %option{ value: 'true' } Listed
  %option{ value: 'false' } Unlisted

This will work too. Just force the value to be boolean by putting an angular expression in for the value.

<select class="span9" ng-model="proposal.formalStoryboard">
    <option value="{{false}}" 
           ng-selected="proposal.formalStoryboard === false">
           Not Included
    </option>
    <option value="{{true}}"
            ng-selected="proposal.formalStoryboard === true">
            Included
    </option>
</select>

I created sample for you, please check this out.

Is it what you want to use model to drive the ui binding?

<div ng-app ng-controller="Ctrl">
    <select class="span9" ng-model="proposal.formalStoryboard">
        <option value="false">Not Included</option>
        <option value="true">Included</option>
    </select>
    <button ng-click="changeValue();">Click</button>
<div>

function Ctrl($scope) {
    $scope.proposal = {};
    $scope.proposal.formalStoryboard = true;

    $scope.changeValue = function () {
        $scope.proposal.formalStoryboard = !$scope.proposal.formalStoryboard;
        console.log($scope.proposal.formalStoryboard);
    }
}

I had very little success with this frustrating issue. My solution, while not too elegant since it's an additional line of code, solved it every time. This may not work in every application.

$scope.myObject.myBooleanProperty = $scope.myObject.myBooleanProperty.toString();

Turning it into a "real" string before trying to rebind it to the model displayed on the page allowed it to correctly select the value.

Angular does a strict comparsion between the Value bind to ng-model and the Values in the given Options. The Values given in the initial Question are the Strings "false" and "true". If the Value of ng-model is of Type bool and defined like {"Value":false}, Angulars strict === comparsion between string and bool does never match so the select-box is empty.

The real Problem is- if you select a Value, the Type changed from bool to string ({"Value":false} --> {"Value":"false"})can cause errors if posted back.

The best Solution for both issues for me was the one of Thiago Passos in this Post. ( https://stackoverflow.com/a/31636437/6319374 )

<script type='text/javascript'>
function MyCntrl($scope) {<!--from   ww w . j  a  v a 2s.  c om-->
  $scope.mybool = true;
}

</script>
</head>
<body>
  <div ng-app="">
  <div ng-controller="MyCntrl">
    <select ng-model="mybool">
        <option value="false">Not Included</option>
        <option value="true">Included</option>
    </select>
    <p>
    Currently selected: {{ mybool }}
   </p>
 </div>
</div>
</body>
</html>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM