【问题标题】:Angular JS: Fetching the data from server before the view has been shown to the userAngular JS:在向用户显示视图之前从服务器获取数据
【发布时间】:2014-07-07 00:43:59
【问题描述】:

我的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;
}

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

【问题讨论】:

  • 抱歉,我不在,无法发布更新!我有这个工作。谢谢两位回答! :-)

标签: angularjs promise angularjs-service


【解决方案1】:

问题在于您的实施。您没有正确解决延迟。我认为Task 方法都返回承诺你需要做这样的事情

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

【讨论】:

    【解决方案2】:

    您的代码中有两处错误:

    • 你有一个多余的 deferred(不需要那个 $q.defer(),它是 deferred anti pattern
    • 当您解决延迟问题时,您不会等待承诺解决。

    由于根据问题,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};
        });
    }
    

    这仍然避免了嵌套。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-03-27
      • 2017-09-07
      • 1970-01-01
      • 2018-02-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-07-21
      相关资源
      最近更新 更多