Angularjs Angular JS:在视图显示给用户之前从服务器获取数据

Angularjs Angular JS:在视图显示给用户之前从服务器获取数据,angularjs,promise,angularjs-service,Angularjs,Promise,Angularjs Service,我的config如下所示: app.config(function ($routeProvider) { $routeProvider ... .when('/project/:slug', { templateUrl: 'partials/plaintasks-part.php', controller: 'ProjectCtrl', resolve : {

我的
config
如下所示:

app.config(function ($routeProvider) {
    $routeProvider
        ...
        .when('/project/:slug', {
            templateUrl: 'partials/plaintasks-part.php',
            controller: 'ProjectCtrl',
            resolve : {
                projectDetail : ProjectCtrl.loadProject
            }
        })
        ...
});
loadProject
如下所示:

// Project controller
var ProjectCtrl = app.controller('ProjectCtrl', ...);

ProjectCtrl.loadProject = function( $q, Tasks, $route ){

    var defer = $q.defer();

    var slug = $route.current.params.slug;
    // Tasks.getProjectBySlug() is where I have implemented the http request to get the data from server
    var project = Tasks.getProjectBySlug( slug );
    var tasks = Tasks.getProjectTasks( project.id );

    defer.resolve({ 
        tasks : tasks,
        project : project
    });

    return defer.promise;
}

现在的问题是,它不等待从服务器获取
项目
任务
,而是简单地显示我不想要的视图,除非从服务器获取数据。谁能告诉我,我做错了什么?尽管我在路由中实现了
resolve
,但它为什么不等待数据被提取呢?

问题在于您的实现。您没有正确解析延迟。我认为
Task
方法返回的都是您需要这样做的承诺

Tasks.getProjectBySlug(slug).then(function(project) {
   Tasks.getProjectTasks( project.id ).then (function(tasks) {
      defer.resolve({ 
        tasks : tasks,
        project : project
      });
   })     
});

您的代码中有两个错误:

  • 您有一个多余的延迟(不需要$q.defer(),这是最重要的
  • 当你解决延迟的问题时,你不是在等待承诺的解决
根据问题,由于
getProjectTasks
不是HTTP调用,因此除非有可能发出HTTP请求,否则它不应返回承诺。如果它发出HTTP请求,请在后端编写一个方法,获取slug并返回项目及其任务,因为两次往返的开销非常大昂贵的

然后,您可以将loadProject简化为:

ProjectCtrl.loadProject = function( $q, Tasks, $route ){
     return Task.getProjectBySlug($route.current.params.slug).then(function(project){
          return {tasks:Tasks.getProjectTasks(project.id), project: project};
     });
};
如果您必须打两个电话,您仍然可以:

ProjectCtrl.loadProject = function( $q, Tasks, $route ){  
    var getProject = Task.getProjectBySlug($route.current.params.slug);
    var getTasks = p.then(function(project){ return Tasks.getProjectTasks(project.id);});
    return $q.all([getTasks,getProject]).then(function(project,tasks){
         return {tasks:tasks,project:project};
    });
}

这仍然可以避免嵌套。

抱歉,我不在家,无法发布更新!我已经完成了这项工作。感谢你们两位的回答!:-)