【问题标题】:AngularJS 1.5 ngOptions Comparison for Displaying a Plain ArrayAngularJS 1.5 ngOptions 显示普通数组的比较
【发布时间】:2016-09-16 13:06:28
【问题描述】:

谁能告诉我为什么选择了第一个示例中的模型选项,而第二个示例中没有选择普通数组:

// 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>

即使模型中仍然设置了值,也不会选择尝试不使用 hack 并使用 track by index 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 的任何解释或解决方案都非常好,因为它更简洁且不是 hack。

【问题讨论】:

    标签: angularjs ng-options angularjs-1.5


    【解决方案1】:

    没有找到使用 track by 的解决方案,但是 Select 的 AngularJS 文档有一个使用解析器和格式化程序的解决方案,因此我可以避免在问题中使用 hack。我对其进行了一些调整,因此如果密钥是一个字符串,它将不理会它,否则它会转换它,这似乎有效。任何我看不到的批评或问题请发表评论,否则希望这对某人有所帮助。

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

    【讨论】:

      【解决方案2】:

      是的,问题似乎是选择被绑定到一个非字符串值。如果您执行以下操作,它将起作用:

      //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"
      

      但是,这可能并不比您的第一个示例更“hackish”:

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

      AngularJS ng-option get index查看第一个答案。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-10-28
        • 2016-03-29
        • 2017-07-21
        • 1970-01-01
        • 1970-01-01
        • 2021-06-17
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多