2016-09-15 7 views
0

Может кто-нибудь сказать мне, почему выбран вариант модели в первом примере, а вторая не для простого массива:AngularJS 1,5 ngOptions Сравнение для Отображение массива Plain

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

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

ответ

0

Не нашли решение, используя track by, но у AngularJS docs for Select было решение с использованием анализатора и форматирования, чтобы я мог уйти от использования взлома в вопросе. Я немного изменил его, поэтому, если ключ был строкой, он оставит его в покое, иначе он преобразует его, и это, похоже, сработает. Любые критические замечания или проблемы, которые я не вижу, прошу прокомментировать, иначе надеюсь, что это поможет кому-то.

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

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