Search code examples
angularjsangular-ngmodel

Angular: properly bind a model to a select to show default value


In angular I have a select element with its model:

 <select class="form-control" name="items" id="items" ng-model="myModel">
          <option value ="10">10</option>
          <option value ="20">20</option>
          <option value ="30">30</option>
 </select>
 {{myModel}}

In my controller I have:

$scope.myModel = "20";

When the page is loaded, {{myModel}} is equal to 20, but the select box is empty, instead of displaying 20. Later, if I change the value of that box also {{myModel}} value changes. It seems properly bound. But how can I display correct value on page load (and why does it happen?)

Here's a plnkr to see the problem in action


Solution

  • As demonstrated by a fork of your original plunker, the problem is being caused by the st-table directive.

    This directive is changing your itemsPerPage property into a number. Due to limitations of the angular select directive, ng-model for select can only be a string.

    Note that the value of a select directive used without ngOptions is always a string. When the model needs to be bound to a non-string value, you must either explicitly convert it using a directive (see example below) or use ngOptions to specify the set of options. This is because an option element can only be bound to string values at present.

    You have 3 options which can be used to overcome this situation:

    1. use ng-options to populate the <options>.
    2. Bind your ng-model property to a separate property from the property being passed to st-table.
    3. Convert the model to a string explicitly, as demonstrated in the last code sample on the angular select documentation page:
    .directive('convertToNumber', function() {
      return {
        require: 'ngModel',
        link: function(scope, element, attrs, ngModel) {
          ngModel.$parsers.push(function(val) {
            return parseInt(val, 10);
          });
          ngModel.$formatters.push(function(val) {
            return '' + val;
          });
        }
      };
    });
    
    <select convert-to-number class="form-control" name="items" id="items" 
            ng-model="itemsByPage">
      <option value="10">10</option>
      <option value="20">20</option>
      <option value="30">30</option>
    </select>​
    

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