使用模型号的Angularjs ng-options不会select初始值

我想用一个<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 ,以及其他一些我已经采取但不满意的方法。

select选项正在初始化一个空值,而不是在本例中预期的“mV”。 绑定似乎工作正常,如果您select一个不同的选项 – selectedUnitOrdinal正确更新。

我注意到如果你将初始模型的值设置为一个string而不是数字,那么初始select就起作用(参见小提琴中的#3)。

我真的想ng-options玩数字选项值很好。 我怎样才能达到这个优雅?

ng-select指令的Angular文档解释了如何解决这个问题。 请参阅https://code.angularjs.org/1.4.7/docs/api/ng/directive/select (上一节)。

您可以创build一个convert-to-number指令并将其应用于您的select标签:

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中的指令不处理空值,所以我不得不调整一下。

也许这有点乱,但是如果没有ng选项中的特殊function,结果就可以实现

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

这是因为当你得到unit.id它返回一个string不是一个整数。 JavaScript中的对象将它们的键存储为string。 所以要做到这一点的唯一方法就是用引号括住四位的方法。

编辑

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

你也可以定义filternumber ,这个filter会自动将string值parsing为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); }; }]); 

只要添加克里斯托夫的答案:实现和维护它的最简单方法是制定一个指令:

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的answear在“val”上返回false将无法正常工作。 testing。

Angular将你的id属性看作一个string,加引号:

 self.selectedUnitOrdinal = "4"; 

非常类似于tymeJV的答案,简单的解决方法是将默认select号码转换为像这样的string:

 self.selectedUnitOrdinal = valueThatCameFromServer.toString(); 

这样,你不必硬编码的数字,你可以转换任何收到的价值。 这是一个简单的修复,没有任何filter或指令。

Mathew Berg提供的解决scheme可能会破坏其他使用sting-valuedselect选项的select。 这可能是一个问题,如果你试图写一个通用指令来处理select(就像我做的那样)。

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

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