Загрузите данные в поле со списком по требованию и выбранный элемент
Я работаю над Приложением, где на веб-странице у меня есть почти 20-25 комбинированных списков, и каждый получает данные из webapi асинхронно, используя ajax, и как только мы заполним все комбинированные списки, мы покажем выбранные значения всем комбинированным спискам. На основании данных, которые мы имеем в базе данных.
Чтобы сделать это, при загрузке страницы сначала я показываю индикатор выполнения, затем я использую $.when(сделать все вызовы ajax).then(скрыть индикатор выполнения), затем связываю их все при каждом включении ajax.
Загрузка всех списков занимает много времени, и пользователь должен ждать, пока индикатор выполнения не скроется.
Вопрос: Есть ли способ, мы приносим данные для комбинированного списка только тогда, когда пользователь открывает комбинированный список и до этого мы можем показать выбранное значение, которое мы получили из базы данных?
Например: допустим, у нас есть веб-страница со списком стран, чтобы выбрать страну и сохранить ее в базе данных. Когда пользователь заходит на эту страницу в первый раз, страна не будет выбрана, тогда данные будут легко загружать, только когда пользователь откроет комбинированный список, но как только пользователь выберет (скажем, Соединенные Штаты) и нажмет кнопку "Сохранить", тогда пользователь в следующий раз На этой странице он хочет видеть "Соединенные Штаты", выбранные в этом списке. Я не могу выбрать страну ("Соединенные Штаты"), пока не загружу данные для страны и не выберу этот элемент, и, как я уже говорил, для этого требуется много времени, чтобы загрузить и выбрать все комбинированные списки (20-25) на страница.
Я хочу, чтобы все комбинированные списки загружались по требованию, но я также хочу показать сохраненное выбранное значение в БД в пользовательском интерфейсе.
Надеюсь, я объяснил это немного лучше, вся идея в том, чтобы эта страница загружалась быстрее и по требованию.
Любой совет будет оценен.
1 ответ
Немного странно, что загрузка 20-25 комбинированных списков занимает очень много времени. Или варианты по списку большой список? Объем данных не должен быть таким большим.
В любом случае, вы можете сделать запрос при загрузке страницы, когда ваш сервер возвращает элементы с выбранным элементом, и тогда ваше угловое приложение может заполнить эти комбинации. Ваш сервер может сделать запрос БД, например: db.myCollection.find( { $where: "itemSelected != ''" } );
(Синтаксис MongoDB) и вернуть его в формате JSON.
Так checkForceLoad
вероятно, не правильное имя. Это должно быть что-то вроде initItems
где вы загружаете выбранные элементы на странице загрузки из вашего бэкэнда.
Другие комбо заполняются только после клика.
Пожалуйста, посмотрите на демонстрацию ниже (здесь не работает -> похоже на проблему SO с localalstorage) или на эту рабочую скрипку.
В демоверсии я смоделировал поведение с помощью localalstorage, потому что у меня нет доступного бэкэнда. Загрузка по комбо-клику задерживается тайм-аутом, чтобы показать задержку загрузки.
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>