使用模型编号的Angularjs ng-options不选择初始值

时间:2015-01-23 17:02:00

标签: angularjs ng-options angularjs-ng-options

我尝试使用带有<select>的ng-options将数字整数值绑定到相应选项列表。在我的控制器中,我有类似的东西:

myApp.controller('MyCtrl', function() {
    var self = this;

    var unitOptionsFromServer = {
        2: "mA",
        3: "A",
        4: "mV",
        5: "V",
        6: "W",
        7: "kW"
    };

    self.unitsOptions = Object.keys(unitOptionsFromServer).map(function (key) {
        return { id: key, text: unitOptionsFromServer[key] };
    });

    self.selectedUnitOrdinal = 4; // Assume this value came from the server.
});

HTML:

<div ng-controller="MyCtrl as ctrl">
    <div>selectedUnitOrdinal: {{ctrl.selectedUnitOrdinal}}</div>
    <select ng-model="ctrl.selectedUnitOrdinal" ng-options="unit.id as unit.text for unit in ctrl.unitsOptions"></select>
</div>

这里有一个jsFiddle来证明这个问题,以及我采取的一些其他方法,但我并不满意。

正在使用空值初始化选择选项,而不是&#34; mV&#34;正如本例所预期的那样。如果您选择其他选项 - selectedUnitOrdinal正确更新,则绑定似乎可以正常工作。

我注意到如果您将初始模型值设置为字符串而不是数字,则初始选择有效(请参阅小提琴中的#3)。

我真的希望ng-options能够很好地使用数字选项值。我怎样才能做到这一点呢?

12 个答案:

答案 0 :(得分:96)

Angular的ng-select指令文档解释了如何解决此问题。见https://code.angularjs.org/1.4.7/docs/api/ng/directive/select(最后一节)。

您可以创建convert-to-number指令并将其应用于您的选择标记:

<强> JS

module.directive('convertToNumber', function() {
  return {
    require: 'ngModel',
    link: function(scope, element, attrs, ngModel) {
      ngModel.$parsers.push(function(val) {
        return val != null ? parseInt(val, 10) : null;
      });
      ngModel.$formatters.push(function(val) {
        return val != null ? '' + val : null;
      });
    }
  };
});

<强> HTML

<select ng-model="model.id" convert-to-number>
  <option value="0">Zero</option>
  <option value="1">One</option>
  <option value="2">Two</option>
</select>

注意:我发现doc中的指令没有处理空值,所以我不得不稍微调整一下。

答案 1 :(得分:38)

也许它有点乱,但是在ng-options中没有特殊功能就可以实现结果

<select ng-model="ctrl.selectedUnitOrdinal" ng-options="+(unit.id) as unit.text for unit in ctrl.unitsOptions"></select>

答案 2 :(得分:16)

这是因为当你获得unit.id时,它返回一个字符串而不是一个整数。 javascript中的对象将其键存储为字符串。因此,唯一的方法是用引号围绕4。

修改

<select ng-model="ctrl.selectedUnitOrdinal" ng-options="convertToInt(unit.id) as unit.text for unit in ctrl.unitsOptions"></select>

$scope.convertToInt = function(id){
    return parseInt(id, 10);
};

答案 3 :(得分:9)

您还可以定义过滤器number,此过滤器会自动将字符串值解析为int:

<select ng-model="ctrl.selectedUnitOrdinal" ng-options="unit.id|number as unit.text for unit in ctrl.unitsOptions"></select>


angular.module('filters').filter('number', [function() {
        return function(input) {
            return parseInt(input, 10);
        };
    }]);

答案 4 :(得分:8)

只是添加Christophe的衣服:最简单的方法来实现和维护它是指示:

<强> JS:

.directive('convertToNumber', function() {
  return {
    require: 'ngModel',
    link: function(scope, element, attrs, ngModel) {
      ngModel.$parsers.push(function(val) {
        //saves integer to model null as null
        return val == null ? null : parseInt(val, 10);
      });
      ngModel.$formatters.push(function(val) {
        //return string for formatter and null as null
        return val == null ? null : '' + val ;
      });
    }
  };
});

Christophe的衣服无法正常使用&#39; 0&#39;因为它在&#34; val?&#34;上返回false测试

答案 5 :(得分:3)

Angular将您的id属性视为字符串,添加引号:

self.selectedUnitOrdinal = "4";

答案 6 :(得分:3)

与tymeJV的答案非常相似,简单的解决方法是将默认选择号转换为如下字符串:

self.selectedUnitOrdinal = valueThatCameFromServer.toString();

这样,您不必对数字进行硬编码,只需转换任何接收的值即可。这是一个简单的修复,没有任何过滤器或指令。

答案 7 :(得分:2)

我认为其他解决方案过于简单,无法简单地将值设置为整数。我会用:

<select ng-model="model.id">
    <option ng-value="{{ 0 }}">Zero</option>
    <option ng-value="{{ 1 }}">One</option>
    <option ng-value="{{ 2 }}">Two</option>
</select>

答案 8 :(得分:1)

<select ng-model="ctrl.selectedUnitOrdinal" ng-options="+(unit.id) as unit.text for unit in ctrl.unitsOptions"></select>

答案 9 :(得分:1)

将unitsOptions中的id属性设置为数字

self.unitsOptions = Object.keys(unitOptionsFromServer).map(function (key) {
        return { id: +key, text: unitOptionsFromServer[key] };
    });

http://jsfiddle.net/htwc10nx/

答案 10 :(得分:0)

虽然Mathew Berg提供的解决方案可行,但它可能会破坏使用刺激值选择选项的其他选择。如果您尝试编写一个用于处理选择的通用指令(如我所做的),这可能是一个问题。

一个很好的解决方法是检查值是否是一个数字(即使它是一个包含数字的字符串),而且只是进行转换,如下所示:

angular.module('<module name>').filter('intToString', [function() {
        return function(key) {
            return (!isNaN(key)) ? parseInt(key) : key;
        };
    }]);

或作为控制器方法:

$scope.intToString = function(key) {
    return (!isNaN(key)) ? parseInt(key) : key;
};

答案 11 :(得分:0)

您可以使用ng-value属性。像这样:

<select ng-model="model.id">
  <option ng-value="0">Zero</option>
  <option ng-value="1">One</option>
  <option ng-value="2">Two</option>
</select>