21

我的问题是我需要在调用控制器和渲染模板之前加载服务。 http://jsfiddle.net/g75XQ/2/

html:

<div ng-app="app" ng-controller="root">
    <h3>Do not render this before user has loaded</h3>            
    {{user}}
</div>
​

JavaScript:

angular.module('app', []).
factory('user',function($timeout,$q){
    var user = {};            
    $timeout(function(){//Simulate a request
        user.name = "Jossi";
    },1000);
    return user;
}).
controller('root',function($scope,user){

    alert("Do not alert before user has loaded");
    $scope.user = user;

});
​

​</p>

4

6 回答 6

14

您可以使用手动初始化来推迟角度应用程序的初始化,而不是使用ng-app属性自动初始化。

// define some service that has `$window` injected and read your data from it
angular.service('myService', ['$window', ($window) =>({   
      getData() {
          return $window.myData;
      }
}))    

const callService = (cb) => {
   $.ajax(...).success((data)=>{
         window.myData = data;
         cb(data)
   })
}

// init angular app 
angular.element(document).ready(function() {
       callService(function (data) {
          doSomething(data);
          angular.bootstrap(document);
       });
});

您的函数在哪里callService执行 AJAX 调用并接受成功回调,它将初始化 Angular 应用程序。

还要检查ngCloak指令,因为它可能是您需要的一切。

或者,在使用ngRoute时,您可以使用resolve属性,为此您可以看到 @honkskillet 答案

于 2012-09-30T00:28:28.180 回答
9

甚至比手动引导更好(这也不总是一个坏主意)。

angular.module('myApp', ['app.services'])
   .run(function(myservice) {
      //stuff here.
   });
于 2013-03-04T18:29:06.400 回答
4

正如我在评论中所说,在控制器中处理卸载状态会容易得多,您可以从 $q 中受益,使其非常简单:http: //jsfiddle.net/g/g75XQ/4/

如果你想在加载用户时在控制器中做点什么:http: //jsfiddle.net/g/g75XQ/6/

编辑:要延迟路由更改直到加载某些数据,请查看此答案:延迟 AngularJS 路由更改直到模型加载以防止闪烁

于 2012-09-30T16:15:40.897 回答
4

实现这一点的正确方法是在路由定义上使用 resolve 属性:请参阅http://docs.angularjs.org/api/ngRoute.$routeProvider

然后使用 $q 服务创建并返回一个承诺;还使用 $http 发出请求并在响应时解决承诺。

这样,当路由被解析并加载控制器时,promise 的结果将已经可用并且不会发生闪烁。

于 2013-09-09T14:57:49.377 回答
1

您可以在 .config $routeProvider 中使用解析。如果返回一个 Promise(就像这里一样),则在解决或拒绝路由之前不会加载该路由。此外,返回值将可用于注入控制器(在本例中为 Somert)。

angular.module('somertApp')
  .config(function($routeProvider) {
    $routeProvider
      .when('/home/:userName', {
        /**/
        resolve: {
          Somert: function($q, $location, Somert) {
            var deferred = $q.defer();
            Somert.get(function(somertVal) {
              if (somertVal) {
                deferred.resolve(somertVal);
              } else {
                deferred.resolve();
                $location.path('/error/'); //or somehow handle not getting
              }
            });
            return deferred.promise;
          },
        },
      });
  });
于 2015-09-10T21:39:49.333 回答
0

有几种方法,有些方法比其他方法更先进,但在您的情况下 ng-hide 可以解决问题。见http://jsfiddle.net/roytruelove/g75XQ/3/

于 2012-09-29T23:54:55.310 回答