Angularjs ng-параметры, использующие число для модели, не выбирают начальное значение



Я пытаюсь использовать ng-options с <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.
});


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", как ожидалось в этом примере. Привязка кажется чтобы работать нормально, если вы выберете другой параметр -- selectedUnitOrdinal обновления правильно.



Я заметил, что если вы установите начальное значение модели в строку вместо числа, то первоначальный выбор работает (см. #3 в скрипке).



Я действительно хотел бы, чтобы ng-options играли хорошо с числовыми значениями опций. Как я могу достичь этого элегантно?

479   9  

9 ответов:

угловая документация для

может быть, это немного грязно, но результат может быть достигнут без специальных функций прямо в NG-options

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

это потому, что когда вы получаете unit.id он возвращает строку, а не целое число. Объекты в javascript хранят свои ключи в виде строк. Таким образом, единственный способ сделать это-ваш подход к окружению 4 цитатами.

Edit

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

вы также можете определить фильтр 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);
        };
    }]);

просто добавить answear Кристофа: самый простой способ достичь и поддерживать его - сделать директиву:

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

answear Кристофа не будет работать правильно Для '0', поскольку он возвращает false на " val?" испытание.

угловой видит ваш id свойство в виде строки, добавьте кавычки:

self.selectedUnitOrdinal = "4";

очень похоже на ответ tymeJV, простым обходным путем является преобразование номера выбора по умолчанию в строку следующим образом:

self.selectedUnitOrdinal = valueThatCameFromServer.toString();

таким образом, вам не нужно жестко кодировать число, вы можете просто преобразовать любое полученное значение. Это легко исправить без каких-либо фильтров или директив.

в то время как решение, предоставленное Mathew Berg works, вероятно, сломает другие варианты выбора, которые используют параметры выбора sting-valued. Это может быть проблемой, если вы попытаетесь написать одну универсальную директиву для обработки выбирает (как я сделал).

хороший обходной путь-проверить, является ли значение числом (даже если это строка, содержащая число) и только чем сделать преобразование, например:

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;
};
<select ng-model="ctrl.selectedUnitOrdinal" ng-options="+(unit.id) as unit.text for unit in ctrl.unitsOptions"></select>

Comments

    Ничего не найдено.