【问题标题】:How to preload JSON data so its available when Angularjs module is ready如何预加载 JSON 数据以便在 Angularjs 模块准备好时可用
【发布时间】:2014-01-09 00:39:52
【问题描述】:

我有一个非常简单的应用程序,它使用控制器内部的 $http.get 加载 JSON 数组。它将结果数据分配给范围,HTML 重复结果以显示列表。这是一个非常简单的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,以便在控制器准备好并且没有阻塞时准备好......然后将该数据放入范围?

【问题讨论】:

  • 你确定你的函数是在 onload() 事件之后被调用的吗?如果是这样,您可以在 onload() 本身之前调用它,从而节省这 3 秒。你可能想看看this question.

标签: json angularjs


【解决方案1】:

您可以使用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;

});

这样,您甚至可以在任何与控制器相关的代码执行之前进行异步调用。

【讨论】:

  • 感谢您的回复。这有效,但我如何使用module.run。我只是将“listService.loadList()...”放入我的控制器中,但它具有相同的加载延迟。所以我假设我想像其他答案一样使用 module.run 。如果 listService.loadList 进入我的控制器,那么 module.run 中会发生什么?
  • 两个地方都打同样的电话。首先在module.run,因为它首先执行。如果同时加载了页面,则第二次调用可能只是获取缓存数据。
  • 谢谢。我得到了这个工作,似乎运行加载速度并不比我的控制器快得多。两者都等待 DOM 准备好,这大约需要 1.5 秒。这似乎是我问题的根源。我不想等待 1.5 秒才能开始下载数据。无论如何在 DOM 准备好之前开始获取数据吗?将数据嵌入服务器端是唯一的方法吗?
【解决方案2】:

您可以通过在单独的文件中编写代码(类似于 Chandermani 的 listService)来加载数据,但无需使用 angular。你可以使用 jquery ajax 来加载你的数据。

然后用 Angular 编写一个服务来读取该数据并将其传递给您的控制器。

【讨论】:

  • 我想知道 jQuery 是否会遇到同样的问题,即在 Dom 准备好之前无法加载数据,这在该站点上需要 1. 5 秒。我不想等待 1.5 秒才能开始获取数据。
  • JQuery 没有这个问题。 JQuery 具有 $(document).ready 函数,该函数在 dom 准备好后执行。但是,如果你不使用 ready 函数,你可以编写在页面加载时执行的代码。
【解决方案3】:

听起来您的延迟来自慢速网络 + 服务器,而不是大量数据。

因此,您可以将标签呈现到您的页面中,以便数据将与页面 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 秒,而您通常希望至少在亚秒范围内。

【讨论】:

  • 谢谢。我无法通过页面加载发送数据。数据是从服务中获取的。可以从 mod.run 内部使用 http 方法吗?是的,问题的根源是服务器需要 3 秒。但是,如果我可以在页面加载时获取数据,那么页面需要 3 秒而不是 6 秒。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-04-23
  • 2018-03-30
  • 2015-07-12
  • 2011-05-06
相关资源
最近更新 更多