Angular app解析而非控制器,用于异步预加载数据

时间:2013-07-12 20:34:45

标签: angularjs

This问题,以及许多其他问题,显示在启动应用程序之前需要加载的异步数据使用控制器级resolve

我有很多控制器,每个模块中都有单独定义的路由...如果它们都依赖于数据,使用resolve对我来说是非常荒谬的。我也有依赖于数据的指令(自动完成搜索等)。

是不是有更好的方法:“在显示每个控制器之前加载数据(使用角度服务)”?我需要加载应用程序,异步获取数据,并使用ng-show和一些显示加载或控制器模板的rootScope数据。我尝试将它放在app.run中,但无法使其正常工作......该块中的任何异步似乎都会使应用程序崩溃。

帮助?

3 个答案:

答案 0 :(得分:1)

这就是我的所作所为。我不是这个解决方案的忠实粉丝,但它是迄今为止我能够提出的最佳解决方案。

首先,每条路线中可以有多个resolves,如下所示:

resolve: {
  UserAccount: app.resolves('UserAccount'),
  Posts: app.resolves('Posts')
}

由于您无法将应用程序服务注入配置块,因此我在另一个包含我的服务快捷方式的文件中创建了一个大的旧对象:

app.resolves = (function(){
  // Resolves allow us to use `deferred`s to only
  // load our template after the data it requires
  // has been provided by the server.
  var resolve = {};

  resolve.UserAccount =
  ['Users', function (Users) {
     return Users.fetchActive();
  }];

  resolve.Posts =
  ['Posts', function(Posts) {
     return Posts.getAllPosts();
  }];

  // Public API
  // @param string name
  return function (name) {
    return resolve[name]
  };
})();

答案 1 :(得分:1)

我知道这个问题已经过时了,但由于没有接受的答案,也没有一个干净的答案,我也试图解决这个问题。

每个应用程序缺乏一个解决状态现在让我烦恼了一段时间,这就是我最终提出的解决方案:http://jsfiddle.net/gabrielcatalin/cvyq0oys/

简而言之,我创建了一个Angular Module Enhancer(装饰器),它支持另外两种方法: resolve() ready()。只需在加载angular.js之后和实现之前加载AngularEnhancer片段,如下所示:

<script type="text/javascript" src="angular.js">
<script type="text/javascript" src="angularEnhancer.js">
<script type="text/javascript" src="main.js">

这是实现的样子:

angular.module('myApp', [])
    .ready(function() {
        alert('The app is ready to be used!');
    })
    .resolve(['$q', function ($q) {
        // The resolve can wait for a promise to be resolved
        var differed = $q.defer();

        setTimeout(function() {
            differed.resolve();    
        }, 1000);

        return differed.promise;

        // Or a true value
        // return true;

        // Or even a truish value
        // return 'value';
    }])
    .ready(function() {
        // The order of where the ready() appear doesn't matter
        alert('This is just another alert to show that it can have as many as possible!');
    }); 

和html:

<body>
    <div ng-if="!appReady" class="splash-screen">This is just the splash screen!</div>
    <div ng-if="appReady">Welcome to the app!</div>

    <script>
        angular.element(document).ready(function() {
            angular.bootstrap(document, ['myApp']);
        });
    </script>
</body>

希望看到你们的一些评论!

答案 2 :(得分:0)

我认为,由于没有明显的方法来进行应用级解析配置,因此您可以做的最好的事情是使用装饰器修改$routeProvider功能。通过这种方式,您可以检查是否在每个应用程序路由上设置了resolve配置,并添加/合并了一个特殊的解析承诺,该承诺将加载异步数据或继续使用所需的数据,并具有测试中心点的好处或在需要时修改。

我现在正在努力解决同样的问题。我将尝试在此处制作通用/可重复使用的代码,并很快在GitHub上发布我的解决方案。我也会尝试在这里用适当的例子来更新这个答案。