Загрузите данные в поле со списком по требованию и выбранный элемент

Я работаю над Приложением, где на веб-странице у меня есть почти 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>

Другие вопросы по тегам