63

<select>整数値を対応するオプションのリストにバインドするために、 ng-options を a とともに使用しようとしています。私のコントローラーには、次のようなものがあります。

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と、私が取ったが満足していない他のいくつかのアプローチがあります。

選択オプションは、この例で予想される「mV」ではなく、空の値で初期化されています。別のオプションを選択すると、バインドは正常に機能するようです。selectedUnitOrdinal は適切に更新されます。

初期モデル値を数値ではなく文字列に設定すると、初期選択が機能することに気付きました (フィドルの #3 を参照)。

私は本当に ng-options が数値のオプション値でうまくいくことを望んでいます。どうすればこれをエレガントに達成できますか?

4

12 に答える 12

107

このディレクティブに関する Angular のドキュメントには、ng-selectこの問題の解決方法が説明されています。https://code.angularjs.org/1.4.7/docs/api/ng/directive/select (最後のセクション)を参照してください。

ディレクティブを作成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>

注: ドキュメントのディレクティブは null を処理しないことがわかったので、少し調整する必要がありました。

于 2015-12-06T05:01:24.463 に答える
46

少し面倒かもしれませんが、ng-options で特別な関数を使用しなくても結果を得ることができます

<select ng-model="ctrl.selectedUnitOrdinal" ng-options="+(unit.id) as unit.text for unit in ctrl.unitsOptions"></select>
于 2015-12-29T05:57:24.670 に答える
9

クリストフの答えを追加するだけです:達成して維持する最も簡単な方法は、指示を出すことです:

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

クリストフの回答は、「val?」で false を返すため、「0」では正しく機能しません。テスト。

于 2015-12-11T09:40:48.863 に答える
9

filter を定義することもできます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);
        };
    }]);
于 2015-07-26T08:22:38.627 に答える
3

tymeJV の回答と非常によく似ていますが、簡単な回避策は、デフォルトの選択番号を次のような文字列に変換することです。

self.selectedUnitOrdinal = valueThatCameFromServer.toString();

この方法では、数値をハードコードする必要はなく、受け取った値を変換するだけで済みます。フィルターやディレクティブなしで簡単に修正できます。

于 2016-08-04T08:13:06.167 に答える