2012-12-04 45 views
0

最近我一直在研究一个网络应用程序,我需要一个<select>元素在一年中的每一天。告诉AngularJS更新选定的选项

所以我做了这样的事情,其中​​daysOfYear是一年中所有日子的数组,并且availableValues是包含所有可能值的数组。

<div ng-repeat="day in daysOfYear"> 
    <select ng-model="day.value" ng-options="value for value in availableValues"></select> 
</div> 

的问题是,它是非常很慢,像增加5秒钟的加载在Firefox,在此期间,浏览器是完全冻结。请注意,计算daysOfYear时已经有2秒的冻结时间。没有选择我有一个2秒的冻结,与选择我有一个7秒的冻结,所以我敢肯定,这是由选择造成的。每当我改变一个选择的值时,还有一个额外的小冻结。

因此,我决定按照我在新闻组上阅读的建议,编写自己的模块,填写<select>。 我的模块(请参阅下面的代码)将任何<select>app-typeslist指令添加到数组。然后从服务器加载列表options,列表中的所有元素都填充了给定的选项。

问题是AngularJS在选项列表中没有检测到这种修改。 <select>没有value属性,并且包含表示“无效值”状态的附加<option>元素。 有没有办法告诉AngularJS我希望它更新这个选择?

谢谢。


这里是模块的源代码。我不认为有必要在所有回答这个问题,但我猜你会问反正:

(function() { 
    var elementsList = $(); 
    var html = null; 
    angular 
     .module('elementsTypes', []) 
     .config(function($compileProvider) { 
      $compileProvider.directive('appTypeslist', function() { 
       var directiveDefinitionObject = { 
        link: function(scope, element, attrs) { 
         elementsList.push($(element)); 
         if (html) 
          $(html).each(function() { $(this).clone().appendTo(element); }); 
        } 
       }; 
       return directiveDefinitionObject; 
      }); 
     }) 
     .run(function($http, $rootScope) { 
      $http.get(url of the types).success(function(data) { 
       html = $(); 
       angular.forEach(data, function(category) { 
        var gr = $('<optgroup/>').attr('label', category.description); 
        angular.forEach(category.elements, function(elem) { 
         $('<option/>').attr('value', elem.name).text(elem.description).appendTo(gr); 
        }); 
        html.push(gr); 
       }); 
       elementsList.each(function() { 
        var e = this; 
        $(html).each(function() { $(this).clone().appendTo(e); }); 
       }); 
      }); 
     }); 
})(); 

回答

0

好了,所以我完全从<select>取出ng-model,并延长我的模块包括绑定。

(function() { 
    var elementsList = $(); 
    var html = null; 

    var refreshElement = function(node) { 
     var newVal = $(node).data('appTypeslist'); 
     $(node).val(newVal); 
    }; 

    angular 
     .module('elementsTypes', []) 
     .config(function($compileProvider) { 
      $compileProvider.directive('appTypeslist', function() { 
       var directiveDefinitionObject = { 
        link: function(scope, element, attrs) { 
         elementsList.push(element); 
         if (html) 
          $(html).each(function() { $(this).clone().appendTo(element); }); 
         scope.$watch(attrs.appTypeslist, function(newVal) { 
          $(element).data('appTypeslist', newVal); 
          refreshElement(element); 
         }); 
         $(element).change(function() { 
          $(element).data('appTypeslist', $(this).val()); 
          scope.$apply(attrs.appTypeslist + ' = "' + $(this).val().replace(/([\\"'])/g, "\\$1").replace(/\0/g, "\\0") + '"'); 
          refreshElement(element); 
         }); 
        } 
       }; 
       return directiveDefinitionObject; 
      }); 
     }) 
     .run(function($http, $rootScope) { 
      $http.get(url).success(function(data) { 
       html = $(); 
       angular.forEach(data, function(category) { 
        var gr = $('<optgroup/>').attr('label', category.description); 
        angular.forEach(category.elements, function(elem) { 
         $('<option/>').attr('value', elem.name).text(elem.description).appendTo(gr); 
        }); 
        html.push(gr); 
       }); 
       elementsList.each(function() { 
        var e = this; 
        $(html).each(function() { $(this).clone().appendTo(e); }); 
        refreshElement(e); 
       }); 
      }); 
     }); 
})();