0

最初の例でモデルオプションが選択され、2番目の例ではプレーン配列が選択されていない理由を誰か教えてください:

// Plain old array
vm.owner = ['example', 'example2', 'example3', ...];

モデルの場所vm.model.address.owner = 2;

// EXAMPLE 1 - Works
// Force index to be a number: using id*1 instead of it being a string:
// and the option ('example3') is selected based on the model value of 2 
// indicating the index
<select id="owner"
        name="owner"
        placeholder="Residential Status"
        ng-model="vm.model.address.owner"
        ng-required="true"
        ng-options="id*1 as owner for (id, owner) in vm.owner">
    <option value="">Select Value</option>
</select>

ハックを使用せずに track by を代わりに使用しようとすると、値がまだモデルに設定されていても、インデックス 2 が選択されません。

// EXAMPLE 2 - Doesn't Work
// Markup doesn't show value to be a string: using track by, but the 
// option set in the model doesn't cause the option to be selected it 
// remains as the default with a value of ''
<select id="owner"
        name="owner"
        placeholder="Residential Status"
        ng-model="vm.model.address.owner"
        ng-required="true"
        ng-options="owner for (id, owner) in vm.owner track by id">
    <option value="">Select Value</option>
</select>

ngOptions は非常に紛らわしいので、例 2 の説明や解決策は、よりクリーンでハックではないため、素晴らしいでしょう。

4

2 に答える 2

0

を使用した解決策は見つかりませんでしたtrack byが、Select の AngularJS ドキュメントには、パーサーとフォーマッターを使用した解決策があったため、問題のハックを使用することから逃れることができました。少し調整したので、キーが文字列の場合はそのままにし、そうでない場合は変換します。これはうまくいくようです。私が見ていない批判や問題はコメントしてください。

(function () {

    'use strict';

    /**
     * Binds a select field to a non-string value via ngModel parsing and formatting,
     * which simply uses these pipelines to convert the string value.
     * @constructor
     * @ngInject
     * ---
     * NOTE: In general matches between a model and an option is evaluated by strict
     * comparison of the model value against the value of the available options.
     * Setting the option value with the option's "value" attribute the value
     * will always be a "string", which means that the model value must also
     * be a string, otherwise the select directive cannot match them
     * reliably.
     */
    function selectConvertKey(_) {

        return {
            require: 'ngModel',
            link: function ($scope, $element, $attrs, $ctrl) {

                var ngModelCtrl = $ctrl;

                // Do nothing if no ng-model
                if (!ngModelCtrl) {
                    return;
                }

                // ---
                // PRIVATE METHODS.
                // ---

                /**
                 * Convert the key to a number if the key is a number.
                 * @param key
                 * @returns {Number}
                 * ---
                 * NOTE: Using Number() instead of parseInt() means that a string
                 * composed of letters and numbers, and start with a number will
                 * not be converted.
                 */
                function selectConvertKeyParser(key) {

                    var keyAsNumber = Number(key);

                    // Check if the key is not a number
                    if(_.isNaN(keyAsNumber)) {
                        return key;
                    }

                    return keyAsNumber;
                }

                /**
                 * Convert the key to a string.
                 * @param key
                 * @returns {string}
                 */
                function selectConvertKeyFormatter(key) {
                    return '' + key;
                }

                // ---
                // MODEL PROPERTIES.
                // ---

                /**
                 * Formatters used to control how the model changes are formatted
                 * in the view, also known as model-to-view conversion.
                 * ---
                 * NOTE: Formatters are not invoked when the model is changed
                 * in the view. They are only triggered if the model changes
                 * in code. So you could type forever into the input, and
                 * the formatter would never be invoked.
                 */
                ngModelCtrl.$formatters.push(selectConvertKeyFormatter);

                /**
                 * Parsers used to control how the view changes read from the
                 * DOM are sanitized/formatted prior to saving them to the
                 * model, and updating the view if required.
                 */
                ngModelCtrl.$parsers.push(selectConvertKeyParser);
            }
        };
    }

    selectConvertKey.$inject = [
        '_'
    ];

    angular
        .module('app')
        .directive('selectConvertKey', selectConvertKey);

})();
于 2016-09-16T00:31:05.360 に答える
0

はい、選択が非文字列値にバインドされていることが問題のようです。次のようにすると、うまくいきます。

//controller
vm.model.address.owner = "2"

//html
ng-options="id as owner for (id, owner) in vm.owner"

Angularjs ng-options using number for model does not select initial value を参照してください。

また、モデル値を数値 (「2」ではなく 2) のままにしたい場合は、次のようにします。

ng-options="vm.owner.indexOf(owner) as owner for (id, owner) in vm.owner"

ただし、それは最初の作業例よりも「ハック」ではない場合があります。

ng-options="id*1 as owner for (id, owner) in vm.owner">

AngularJS ng-option get indexの最初の回答を参照してください。

于 2016-09-16T05:06:28.510 に答える