2013-12-20 1 views
9

У меня очень простое приложение, которое загружает массив JSON с использованием $ http.get внутри контроллера. Он присваивает данные результата областям, и HTML повторяет результаты, чтобы отобразить список. Это очень простой угловой пример.Как предварительно загрузить данные JSON, чтобы он был доступен, когда модуль Angularjs готов

function ViewListCtrl($scope, $http) { 

$scope.shoppinglist = []; 

$scope.loadList = function() { 

    var httpRequest = $http({ 
     method: 'POST', 
     url: 'viewList_service.asp', 
     data: '' 

    }).success(function (data, status) { 
     $scope.shoppinglist = data; 
    }); 

}; 

$scope.loadList(); 

} 

При тестировании на медленном сервере я понял, что задержка блокировки 3 секунды раздирает область повтора. Отладка показала мне, что мой контроллер не пытается получить данные до загрузки страницы. Моя страница занимает 3 секунды для загрузки. Затем я должен подождать еще 3 секунды для загрузки данных json.

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

Я искал все, и ближайшая вещь, которую я нашел, была «разрешена», но я не использую маршруты. Это очень простой список и никаких маршрутов или шаблонов.

Как загрузить JSON, как только страница начнет визуализироваться, так что она готова, когда контроллер готов и нет блокировки ... и затем получить эти данные в область видимости?

+0

Вы уверены, что ваша функция вызывается после события onload()? Если это так, вы можете вызвать его перед самой загрузкой(), тем самым сохраняя эти 3 секунды. Вы можете взглянуть на [этот вопрос.] (Http://stackoverflow.com/questions/6944037/how-to-run-java-script-code-before-page-load) – Sangram

ответ

0

Похоже, что ваша латентность исходит из медленной сети + сервера, а не большого количества данных.

Итак, вы можете отобразить тег на своей странице, чтобы данные были отправлены вместе со ответным HTML-ответом. Недостатком является то, что вы жестко кодируете свои данные на своей странице. Этот тег будет в основном предварять кеш $ http вашими данными.

var listJson = {...json data here, rendered server-side...}; 

mod.run(function($cacheFactory) { 
    var cache = $cacheFactory('yourListCacheId'); 
    cache.put('list-cache-id', listJson); 
    // store "cache" somewhere you can retrieve it, such as a service or value. 
}); 

Затем либо используйте свойство кеша $ http, либо оберните $ http в пользовательскую службу, которая проверяет кеш.

Конечно, корень проблемы заключается в том, что ваш сервер занимает 3 секунды на запрос, когда вы обычно хотите, чтобы не менее в подсезонной области.

+0

Спасибо. Я не могу отправить данные с загрузкой страницы. Данные получаются из службы. Можно ли использовать метод http изнутри mod.run? Да, корень проблемы - сервер занимает 3 секунды.Однако, если я могу получить данные во время загрузки страницы, тогда страница займет 3 секунды вместо 6. – user2341148

3

Вы можете использовать метод module.run. Выполняется после завершения этапа конфигурации. Для того, чтобы воспользоваться этим вам нужно создать сервисный завод, который делает фактический запрос и кэширует результат

module("myapp",[]).factory('listService', function($q,$http) { 
    var listData; 
    var defer = $q.defer(); 
    return { 
     loadList: function() { 
      if(listData) { 
       defer.resolve(listData); 
      } 
      else { 

       var httpRequest = $http({ 
       method: 'POST', 
       url: 'viewList_service.asp', 
       data: '' 
      }) 
      .success(function(data) { 
       listData=data; 
       defer.resolve(listData); 
      } 
     } 
     return defer.promise; 
    } 
} 
}); 

В контроллере вы все еще используете завод, чтобы получить данные с обещанием затем оберткой.

listService.loadList().then(function(data) { 
    $scope.shoppinglist=data; 

}); 

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

+0

Благодарим вас за ответ. Это работает, но я использую module.run. Я просто поместил в свой контроллер «listService.loadList() ...», но он имеет одинаковую задержку загрузки. Поэтому я предполагаю, что я предполагаю использовать module.run, как и другой ответ. Если listService.loadList входит в мой контроллер, то что входит в module.run? – user2341148

+0

Тот же звонок идет в оба места. Сначала в 'module.run', потому что он выполняется первым. Если страница тоже загружается, а второй вызов может просто получить данные кэша. – Chandermani

+0

Спасибо. Я получил эту работу, и кажется, что запуск не загружается намного быстрее, чем мой контроллер. Оба ждут, когда DOM будет готов, и это займет около 1,5 секунд. Это, похоже, является источником моей проблемы. Я не хочу ждать 1,5 секунды, чтобы начать загрузку данных. Нужно ли вообще начать получать данные до того, как DOM будет готов? Единственный способ иметь встроенную серверную часть данных? – user2341148

0

Вы можете загрузить данные, написав код (что-то вроде списка Chandermani listService) в отдельном файле, но без использования углового. вы можете использовать jquery ajax для загрузки ваших данных.

Затем напишите сервис в угловом формате, чтобы прочитать эти данные и передать их контроллеру.

+0

Интересно, будет ли у jQuery такая же проблема, так как она не может загружать данные до тех пор, пока Dom не будет готов, а на этом сайте займет 1 5 секунд. Я не хочу ждать 1,5 секунды, чтобы начать получать данные. – user2341148

+1

У JQuery нет этой проблемы. JQuery имеет функцию $ (document) .ready, которая действует после того, как dom готов. Но если вы не используете функцию готовности, вы можете написать код, который выполняется во время загрузки страницы. – Alborz

Смежные вопросы