AngularJS - 仅在解决所有承诺后显示路线

时间:2015-01-30 05:04:21

标签: angularjs

我尝试在承诺解决后才加载路线

    var app = angular.module("thethaoso", ["ngRoute"]);
app.config(['$routeProvider', '$locationProvider', function ($routeProvider) {

    $routeProvider

        .when('/', {     
            resolve: {
               message: function (repoService) {
                    return repoService.getMsg();
                }
            }
        });

}]);

app.factory('repoService', function ($http) {
    return {
        getMsg: function () {
            return "hihihi";
        }
    };
});
app.controller('teamLoadCtrl', function ($scope,message) {
    $scope.message= message;

});

查看:

<div ng-app='thethaoso' ng-controller='teamLoadCtrl'>
    {{message}}
</div>

总是得到错误错误:[$ injector:unpr] http://errors.angularjs.org/1.3.7/ $ injector / unpr?p0 = messageProvider%20%3C-%20message%20%3C-%20teamLoadCtrl

http://jsfiddle.net/c0y38yp0/5/

的完整代码

我错过了什么吗?

谢谢大家。

3 个答案:

答案 0 :(得分:1)

问题是您没有指定模板和控制器来解析消息对象。如果您使用以下语法,它将起作用。

.when("/", {
    templateUrl: "yourView.html",
    controller: "yourController",
    resolve: {
        message: function(yourService){
            return yourService.get();
    }
}

这是一个有效的jsfiddle:http://jsfiddle.net/c0y38yp0/10/

您也可以在控制器中手动解决承诺,如下所示:

repoService.getMsg()
    .then(function (msg) {
        $scope.message = msg;
    }

当承诺如上所述解析到范围时,ui将更新。您可以显示加载栏并使用ng-hide使页面在加载时感觉流畅。

答案 1 :(得分:1)

当您解决时,服务必须返回承诺而不是值。

以下是示例服务

app.factory('repoService', function ($http, $q) {
    var user = {};
    var q = $q.defer();

    $http.get('https://api.github.com/users/Serhioromano')
        .success(function(json){
          user = json;
          q.resolve();
        }).error(function(){
          q.reject();
        });


    return {
        promise: function() {
          return q.promise;
        },
        get: function() {
          return user;
        }
    };
});

这里的要点是你只返回承诺。您处理如何保存结果。然后您可以像get()一样使用此结果。您知道,当您致电get()已设置user变量时,因为承诺为resolve

现在在路由器中。

app.controller('MainCtrl', function($scope, repoService) {
  $scope.user = repoService.get();
});

app.config(function ($routeProvider, $locationProvider) {
    $routeProvider
      .when('/', { 
          templateUrl: '/view.html',
          controller: 'MainCtrl',
          resolve: {
             message: function (repoService) {
                  return repoService.promise();
              }
          }
      })
     .otherwise({ redirectTo: '/' });
});
  1. 您通过repoService.promise()
  2. 返回承诺
  3. 仅在该承诺解决后才会触发控制器repoService.get()
  4. 所以你得到你的数据。

    代码中的另一件事是,您使用了ng-controller。但是这个东西没有绑定到路由器,因此它可以避免它被解决。您必须删除ng-controller并使用控制器路由器controller: 'MainCtrl',

    这会影响您的HTML

    <body ng-app="myapp">
    
      <ng-view></ng-view>
    
      <script type="text/ng-template" id="/view.html">
        <p>Hello {{user.name}}!</p>
      </script>
    <body>
    

    你必须使用<ng-view>在那里包含子模板,然后在子模板中你可以使用控制器的范围。

    请参阅plunker

答案 2 :(得分:0)

您发布的代码存在一些问题,与您尝试从中获取灵感的代码形成鲜明对比。

使用$routeProvider解析路线时,结果将应用于元素<ng-view></ngview>,而不是您指定的基本元素<div>。如果没有<ng-view>元素,$routeProvider就无法将正确的控制器绑定到正确的html片段。使用ng-controller在呈现dom元素时实例化控制器实例,并且不允许按照您的尝试将参数传递给控制器​​。因此,由于未知的message对象导致您的分辨率错误。实际上,message实例之外无法使用$routeProvider