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

Bra*_*ite 60 angularjs ng-options angularjs-ng-options

我正在尝试使用ng-options和a <select>将数字整数值绑定到相应选项的列表.在我的控制器中,我有这样的事情:

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.
});
Run Code Online (Sandbox Code Playgroud)

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>
Run Code Online (Sandbox Code Playgroud)

这里有一个jsFiddle演示了这个问题,以及我采取的一些其他方法,但我并不满意.

正在使用空值初始化select选项,而不是在此示例中预期的"mV".如果您选择其他选项 - selectedUnitOrdinal正确更新,绑定似乎工作正常.

我注意到如果你将初始模型值设置为字符串而不是数字,那么初始选择就可以了(参见小提琴中的#3).

我真的希望ng-options能够很好地使用数字选项值.我怎样才能优雅地实现这一目标?

Chr*_*e L 102

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;
      });
    }
  };
});
Run Code Online (Sandbox Code Playgroud)

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>
Run Code Online (Sandbox Code Playgroud)

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

  • 大部分时间都是*convert-to-string*,只需将*parseInt*更改为*String* (3认同)
  • 好的解决方案 但是当你的选择选项中有0时,由于实现,它会给出null.处理这种情况需要稍微调整一下. (2认同)

re-*_*gor 39

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

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

  • 这真的是最简单的答案.在[jsFiddle](http://jsfiddle.net/LatencyMachine/x75t70pd)中使用的angularJS库版本1.3.10有一个错误,+ unit.id表示法不起作用,但它从1.4.0开始; 看[work jsFiddle](http://jsfiddle.net/x75t70pd/4/) (6认同)
  • 但是期权的价值是:value ="number:0",带有'number' (3认同)

Mat*_*erg 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);
};
Run Code Online (Sandbox Code Playgroud)


zoo*_*lin 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);
        };
    }]);
Run Code Online (Sandbox Code Playgroud)

  • 当你使用`parseInt`时,你应该总是使用一个基数,如下所示:`return parseInt(input,10);` (3认同)

s3r*_*r3k 9

只是为了添加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 ;
      });
    }
  };
});
Run Code Online (Sandbox Code Playgroud)

Christophe的answear对于'0'不能正常工作,因为它在"val"上返回false 测试.


Ted*_*ler 5

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

<select ng-model="model.id">
    <option ng-value="{{ 0 }}">Zero</option>
    <option ng-value="{{ 1 }}">One</option>
    <option ng-value="{{ 2 }}">Two</option>
</select>
Run Code Online (Sandbox Code Playgroud)


小智 5

您可以使用 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>
Run Code Online (Sandbox Code Playgroud)

  • 这是最简单/最容易的解决方案 (2认同)