2016-09-15 160 views
0

誰能告訴我,爲什麼在第一個例子模型選項被選中,而第二個不爲普通數組:AngularJS 1.5 ngOptions的比較顯示普通數組

// 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並使用替代索引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的解決方案,但用於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); 

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

然而,這可能不是任何少「的hackish」比你第一個例子:

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

查看第一個回答AngularJS ng-option get index