我正在开发一个应用程序,在一个网页中我有大约20-25个组合框,每个组合框都使用ajax异步从webapi获取数据,一旦我们填充了所有的组合框,我们就会显示所选的值到所有组合框,基于我们在数据库中的数据。
为了做到这一点,在页面加载时,最初我显示进度条然后我使用$ .when(进行所有ajax调用)。然后(隐藏进度条)然后在每个ajax onsuccess上绑定所有这些。
加载所有组合框需要很长时间,用户必须等到进度条隐藏。
问题: 有没有办法,我们只在用户打开组合框时才提供组合框的数据,直到我们可以显示我们从数据库中获取的选定值?
for ex: 让我们说我们在网页上有一个国家组合框来选择国家并将其保存在数据库中。 第一次用户访问该页面时,将不会选择任何国家/地区,此时,只有当用户打开组合框时才能轻松加载数据,但是一旦用户选择(例如美国)并单击“保存”按钮,则下次用户进入时到那个页面,他想看到美国'在那个组合框中选择。我无法选择国家/地区('美国'),除非我加载国家/地区的数据并选择该项目,正如我所提到的,这样做需要很长时间才能加载并选择所有组合框( 20-25)在页面上。
我想按需加载所有组合框,但我还想在UI上显示db中存储的选定值。
我希望我能更好地解释一下,整个想法是让页面加载更快,更快。
任何建议都将受到赞赏。
答案 0 :(得分:0)
加载20-25个组合框需要很长时间,这似乎有点奇怪。或者每个组合的选项是一个大的列表? 数据量不应该那么大。
无论如何,您可以在页面加载时执行请求,其中您的服务器返回带有所选项目的项目,然后您的角度应用程序可以填充这些组合。您的服务器可以执行db查询,例如:db.myCollection.find( { $where: "itemSelected != ''" } );
(MongoDB语法)并将其作为JSON返回。
所以checkForceLoad
可能不是正确的名称。它应该类似于initItems
,您可以在后端加载页面加载时选定的项目。
其他组合仅在点击后填充。
请查看下面的演示(此处未运行 - >似乎与localstorage的SO问题)或此工作fiddle。
在演示中,我使用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');
};
});
&#13;
<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>
&#13;