2015-08-25 3 views
0

Я работаю над приложением, где на веб-странице у меня есть почти 20-25 списков со списком, и каждый получает асинхронно данные из webapi с помощью ajax, и как только мы получим все заполненные поля со списком , то мы покажем выбранные значения для всех списков со списком, основываясь на данных, которые мы имеем в базе данных.Загружать данные по выпадающему элементу запроса и выбранному элементу

Для этого при загрузке страницы изначально я показываю индикатор выполнения, тогда я использую $ .when (делать все вызовы ajax). Then (скрывать индикатор выполнения), а затем привязывать их все к каждому ajax onsuccess.

Загрузка всех выпадающих списков занимает много времени, и пользователь должен ждать, пока индикатор выполнения не будет скрыт.

Вопрос: Есть ли способ, мы только принести данные для выпадающего списка только тогда, когда пользователь открывает выпадающий и до, что мы можем показать выбранное значение, которое мы получили из базы данных?

для: Позволяет сказать, что у нас есть поле со списком стран на веб-странице, чтобы выбрать страну и сохранить ее в базе данных. Первый пользователь приходит на эту страницу, в то время не будет выбранной страны, ее легко загружать данные только тогда, когда пользователь открывает combobox, но как только пользователь выбирает (скажем, Соединенные Штаты) и нажимает кнопку «Сохранить», то в следующий раз пользователь приходит к этой странице, он хочет увидеть «Соединенные Штаты», выбранные в этом поле со списком. Я не могу выбрать страну («Соединенные Штаты»), если я не загружу данные для страны и не выбираю этот элемент, и, как я уже упоминал, для этого требуется много времени для загрузки и выбора всех списков со списком (20-25) страница.

Я хочу, чтобы все загрузки comboboxes выполнялись по требованию, но я также хочу показать сохраненное выбранное значение в db в пользовательском интерфейсе.

Надеюсь, я объяснил это немного лучше, вся идея состоит в том, чтобы сделать загрузку страницы быстрее и требовать.

Любые советы будут оценены.

+0

Вы можете сделать это довольно легко, установив печенье.Будет ли это работать на вас? – jonmrich

ответ

0

Кажется немного странным, что загрузка 20-25 выпадающих списков занимает очень много времени. Или варианты для каждого комбо большого списка? Объем данных не должен быть таким большим.

В любом случае, вы можете сделать запрос на загрузку страницы, где ваш сервер возвращает элементы с выбранным элементом, а затем ваше угловое приложение может заполнять эти комбо. Ваш сервер мог бы выполнить db-запрос, например: db.myCollection.find({ $where: "itemSelected != ''" }); (синтаксис MongoDB) и вернуть его как JSON.

Таким образом, checkForceLoad, вероятно, не является правильным названием. Это должно быть что-то вроде initItems, где вы загружаете выбранные элементы при загрузке страницы с вашего сервера.

Другие комбо только заселены после нажатия.

Пожалуйста, взгляните на демонстрационную версию ниже (не работает здесь -> похоже на проблему SO с localstorage) или в этой работе fiddle.

В демоверсии я смоделировал поведение с localstorage, потому что у меня нет бэкэнд доступного. Загрузка на комбинированный клик задерживается таймаутом, чтобы показать задержку загрузки.

angular.module('demoApp', ['LocalStorageModule']) 
 
\t .run(function($rootScope, localStorageService) { 
 
    \t // init test data here because we don't have a backend 
 
    \t $rootScope.modelNames = []; 
 
    \t 
 
    \t var data; 
 
    
 
    \t for (var index=0; index < 20; index++) { 
 
    \t \t $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'}] 
 
       }); 
 
     \t } 
 
     } 
 
\t }) 
 
\t .config(function (localStorageServiceProvider) { 
 
    \t localStorageServiceProvider 
 
     \t .setPrefix('demoApp'); 
 
\t }) 
 
\t .factory('modelService', function($q, $timeout, localStorageService) { 
 
\t \t var service = { 
 
      checkForceLoad: function(names) { 
 
       console.log('check force load'); 
 
       // later returned from array something find().where('model' != '') 
 
      \t var deferred = $q.defer(); // immediatetly resolved promise --> later $http 
 
       var storedObj; 
 
       
 
       angular.forEach(names, function(nameObj) { 
 
        // later just mapping required 
 
       \t storedObj = localStorageService.get(nameObj.name); 
 
       \t 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) { 
 
      \t 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) { 
 
      \t var deferred = $q.defer(); // immediatetly resolved promise --> later $http \t 
 
       var storedData = localStorageService.get(name); 
 
       angular.extend(storedData, {model: model}); 
 
       localStorageService.set(name, storedData); 
 
       deferred.resolve(model); 
 
       return deferred.promise; 
 
      } 
 
     }; 
 
    \t return service; 
 
\t }) 
 
\t .directive('comboBox', function($rootScope, modelService) { 
 
    \t modelService.checkForceLoad($rootScope.modelNames); // runs once 
 
    
 
\t \t return { 
 
      restrict: 'E', 
 
      scope: { 
 
      \t modelName: '=', 
 
       load: '=' 
 
      }, 
 
     \t 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>'+ 
 
      \t '</select></div>', 
 
      controller: function($scope, modelService) { 
 
       
 
     \t \t $scope.save = function(model) { 
 
        //console.log('saving now...'); 
 
    \t \t \t \t modelService.save($scope.modelName, model) 
 
         .then(function(result) { 
 
        \t \t console.log('successfully saved', result); 
 
        }); 
 
    \t \t \t }; 
 
       $scope.loadData = function() { 
 
        console.log('loading data...'); 
 
        if (!$scope.options) {     \t \t \t \t \t 
 
         \t modelService.get($scope.modelName).then(function(result) { 
 
          console.log('loaded data'); 
 
          $scope.model = result.model; 
 
          $scope.options = result.options; 
 
          //$scope.$apply(); 
 
     \t \t \t \t }); 
 
        } 
 
       }; 
 
       
 
       //console.log($scope.load); 
 
       if ($scope.load) { 
 
        //console.log('load on start'); 
 
        $scope.loadData(); 
 
       } 
 
     \t } 
 
     }; 
 
\t }) 
 
    .controller('mainController', function ($scope, localStorageService, modelService) { 
 
    \t $scope.load = true; 
 
    \t console.log($scope.modelNames); 
 
    \t $scope.clear = function() { 
 
     \t 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>