0

我正在开发一个应用程序,其中在网页中我有近 20-25 个组合框,每个组合框都使用 ajax 从 webapi 异步获取数据,一旦我们填充了所有组合框,然后我们将所选值显示给所有组合框,基于我们在数据库中的数据。

为了做到这一点,在页面加载时,最初我显示进度条然后我使用 $.when(make all the ajax calls).then(hide progress bar) 然后在每个 ajax onsuccess 上绑定所有它们。

加载所有组合框需要很长时间,用户必须等到进度条隐藏。

问题: 有什么办法,只有当用户打开一个组合框时,我们才带一个组合框的数据,直到我们可以显示我们从数据库中获得的选定值?

例如: 假设我们在网页上有一个国家组合框来选择国家并将其保存在数据库中。用户第一次访问该页面时,不会选择国家/地区,当时,只有当用户打开组合框时才能轻松加载数据,但是一旦用户选择(比如美国)并单击保存按钮,那么下次用户来到那个页面,他想看到在那个组合框中选择了“美国”。除非我加载国家/地区的数据并选择该项目,否则我无法选择国家/地区(“美国”),正如我所提到的,这样做需要很长时间才能加载并选择所有组合框(20-25)页面。

我想让所有组合框按需加载,但我也想在 UI 的 db 中显示存储的选定值。

我希望我解释得更好一点,整个想法是让页面加载更快和按需加载。

任何建议将被认真考虑。

4

1 回答 1

0

加载 20-25 个组合框需要很长时间,这似乎有点奇怪。或者每个组合的选项是一个大列表?数据量不应该那么大。

无论如何,您可以在页面加载时发出请求,您的服务器正在返回带有所选项目的项目,然后您的 Angular 应用程序可以填充这些组合。您的服务器可以执行如下 db 查询:db.myCollection.find( { $where: "itemSelected != ''" } );(MongoDB 语法)并将其作为 JSON 返回。

所以checkForceLoad可能不是正确的名称。它应该类似于initItems您在从后端加载页面加载时加载所选项目的位置。

其他组合仅在单击后填充。

请查看下面的演示(未在此处运行->似乎与 localstorage 存在 SO 问题)或在此工作小提琴中。

在演示中,我使用 localstorage 模拟了该行为,因为我没有可用的后端。组合点击的加载会因超时而延迟,以显示加载延迟。

angular.module('demoApp', ['LocalStorageModule'])
	.run(function($rootScope, localStorageService) {
    	// init test data here because we don't have a backend
    	$rootScope.modelNames = [];
    	
    	var data;
    
    	for ( var index=0; index < 20; index++ ) {
    		$rootScope.modelNames.push({name: 'test' + index});
            data = localStorageService.get('test' + index);
            if (!data) {
                localStorageService.set('test' + index, {
                    model: '',
                    options: [{
                        value: 'option-1',
                        text: 'Option 1'},
                              {
                                  value: 'option-2',
                                  text: 'Option 2'},
                              {
                                  value: 'option-3',
                                  text: 'Option 3'}]
                });
        	}
        }
	})
	.config(function (localStorageServiceProvider) {
    	localStorageServiceProvider
        	.setPrefix('demoApp');
	})
	.factory('modelService', function($q, $timeout, localStorageService) {
		var service = {
            checkForceLoad: function(names) {
                console.log('check force load');
                // later returned from array something find().where('model' != '')
            	var deferred = $q.defer(); // immediatetly resolved promise --> later $http
                var storedObj;
                
                angular.forEach(names, function(nameObj) {
                    // later just mapping required
                	storedObj = localStorageService.get(nameObj.name);
                	if (storedObj.model !== '') {
                        console.log('force', storedObj.model);
                        nameObj.forceLoad = true;
                    }
                });
                console.log('checkforce', names);
                
                //$timeout(function() {
                deferred.resolve('checked models');
                //}, 500); // simulate async
                return deferred.promise;
            },
            get: function(name) {
            	var deferred = $q.defer(); // immediatetly resolved promise --> later $http
                var storedObj = localStorageService.get(name);
                $timeout(function() {
                    deferred.resolve(storedObj);
                }, 500); // simulate async
                return deferred.promise;
            },
            save: function(name, model) {
            	var deferred = $q.defer(); // immediatetly resolved promise --> later $http	
                var storedData = localStorageService.get(name);
                angular.extend(storedData, {model: model});
                localStorageService.set(name, storedData);
                deferred.resolve(model);
                return deferred.promise;
            }
        };
    	return service;
	})
	.directive('comboBox', function($rootScope, modelService) {
    	modelService.checkForceLoad($rootScope.modelNames); // runs once
    
		return {
            restrict: 'E',
            scope: {
            	modelName: '=',
                load: '='
            },
        	template: '<div><select ng-model="model" ng-click="loadData()" ng-change="save(model)">'+
                '<option ng-selected="model == option.value" ng-repeat="option in options" value="{{option.value}}">{{option.text}}</option>'+
            	'</select></div>',
            controller: function($scope, modelService) {
                
        		$scope.save = function(model) {
                    //console.log('saving now...');
    				modelService.save($scope.modelName, model)
                        .then(function(result) {
                    		console.log('successfully saved', result);
                    });
    			};
                $scope.loadData = function() {
                    console.log('loading data...');
                    if ( !$scope.options ) {                					
                      	modelService.get($scope.modelName).then(function(result) {
                            console.log('loaded data');
                            $scope.model = result.model;
                            $scope.options = result.options;
                            //$scope.$apply();
        				});
                    }
                };
                
                //console.log($scope.load);
                if ( $scope.load ) {
                    //console.log('load on start');
                    $scope.loadData();
                }
        	}
        };
	})
    .controller('mainController', function ($scope, localStorageService, modelService) {
    	$scope.load = true;
    	console.log($scope.modelNames);
    	$scope.clear = function() {
        	localStorageService.clearAll();
            alert('re-run app manually');
        };
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-local-storage/0.2.2/angular-local-storage.js"></script>
<div ng-app="demoApp" ng-controller="mainController">
    <p>Comboboxes are saved in localstorage if changed. On next run only the data with selected values will be loaded. Other combos are loaded on demand.</p>
    <button ng-click="clear()">clear localstorage (just for testing)</button>
    <combo-box model-name="nameObj.name" load="nameObj.forceLoad" ng-repeat-start="nameObj in modelNames"></combo-box>
    {{name.forceLoad}}
    <div ng-repeat-end=""></div>
</div>

于 2015-08-25T23:21:01.757 回答