Angular.js - 在控制器中等待服务从服务器返回值

时间:2022-11-13 19:41:40

In my Angular.js application I'm stucked with such problem. I have service which is called user and I call it on app.run to get user data from server like so:

在我的Angular.js应用程序中,我遇到了这样的问题。我有一个名为user的服务,我在app.run上调用它来从服务器获取用户数据,如下所示:

app.run(function (user, tracking) {
    user.initialize();
    ... // some other code goes here..
});

This simply calls API route and creates $rootScope.user to be available through all application.

这只是调用API路由并创建$ rootScope.user以通过所有应用程序可用。

But somehow controller from time to time loads faster then initializing goes.. and $rootScope inside it doesn't contain user object.

但不知何故控制器不时加载更快,然后初始化..和$ rootScope里面不包含用户对象。

function SomeController($scope, $rootScope, $routeParams) {
   console.log($rootScope.user.name); 
   // sometimes returns error -
   // TypeError: Cannot read property 'name' of undefined
}

So how can I force all controllers load only after initializing to $rootScope went well. I don't want to add $watch on user in every controller.. 'cause it looks like bad decision and makes code ugly.

那么如何在初始化为$ rootScope之后强制所有控制器加载。我不想在每个控制器中为用户添加$ watch ..因为它看起来像是错误的决定并且使代码变得丑陋。

Your suggestions? Thanks!

你的建议?谢谢!

2 个解决方案

#1


3  

My solution is to use resolve option of $routeProvider.when() method.

我的解决方案是使用$ routeProvider.when()方法的resolve选项。

This will prevent controller to load before request to data is finished:

这将阻止控制器在数据请求完成之前加载:

$routeProvider.when('/books', { 
  templateUrl: 'books', 
  controller: 'bookCtrl',
  resolve: {
    appUser: function (user) {
       // we're injecting "user" service
       // and initiliazing it (this method returns $promise)
       return user.initialize();
    }
  }  
});

And inside bookCtrl just injecting appUser as a dependency.

而在bookCtrl里面只是将appUser作为依赖注入。

#2


2  

I had the same problem. The only solution I found was to create some function in the rootScope and call it from the controller. So the app.run function has inside something like that:

我有同样的问题。我找到的唯一解决方案是在rootScope中创建一些函数并从控制器中调用它。所以app.run函数有类似的东西:

scope.initUser = function () {
   if (!user){
   // create
      user.initialize();
   }
};

And then my controller call it at the beginning:

然后我的控制器在开始时调用它:

$rootScope.initUser();

Don't forget to inject the $rootScope into the controller.

不要忘记将$ rootScope注入控制器。

This solution doesn't pretend to be elegant but at least it works...

这个解决方案不是假装优雅,但至少它有效......

I would appreciate if someone suggest better solution...

如果有人建议更好的解决方案我会很感激

#1


3  

My solution is to use resolve option of $routeProvider.when() method.

我的解决方案是使用$ routeProvider.when()方法的resolve选项。

This will prevent controller to load before request to data is finished:

这将阻止控制器在数据请求完成之前加载:

$routeProvider.when('/books', { 
  templateUrl: 'books', 
  controller: 'bookCtrl',
  resolve: {
    appUser: function (user) {
       // we're injecting "user" service
       // and initiliazing it (this method returns $promise)
       return user.initialize();
    }
  }  
});

And inside bookCtrl just injecting appUser as a dependency.

而在bookCtrl里面只是将appUser作为依赖注入。

#2


2  

I had the same problem. The only solution I found was to create some function in the rootScope and call it from the controller. So the app.run function has inside something like that:

我有同样的问题。我找到的唯一解决方案是在rootScope中创建一些函数并从控制器中调用它。所以app.run函数有类似的东西:

scope.initUser = function () {
   if (!user){
   // create
      user.initialize();
   }
};

And then my controller call it at the beginning:

然后我的控制器在开始时调用它:

$rootScope.initUser();

Don't forget to inject the $rootScope into the controller.

不要忘记将$ rootScope注入控制器。

This solution doesn't pretend to be elegant but at least it works...

这个解决方案不是假装优雅,但至少它有效......

I would appreciate if someone suggest better solution...

如果有人建议更好的解决方案我会很感激