Javascript AngularJS 加载服务然后调用控制器并渲染
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12657389/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
AngularJS load service then call controller and render
提问by Jossi
My problem is that i need a service loaded before the controller get called and the template get rendered. http://jsfiddle.net/g75XQ/2/
我的问题是我需要在调用控制器和渲染模板之前加载服务。 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:
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;
});
?
?
?
采纳答案by vittore
You can defer init of angular app using manual initialization, instead of auto init with ng-app
attribute.
您可以使用手动初始化延迟 Angular 应用程序的初始化,而不是使用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);
});
});
where callService
is your function performing AJAX call and accepting success callback, which will init angular app.
callService
您的函数在哪里执行 AJAX 调用并接受成功回调,这将初始化 angular 应用程序。
Also check ngCloak
directive, since it maybe everything you need.
还要检查ngCloak
指令,因为它可能是您需要的一切。
Alternatively, when using ngRouteyou can use resolve
property, for that you can see @honkskillet answer
或者,在使用ngRoute 时,您可以使用resolve
属性,为此您可以看到 @honkskillet 答案
回答by davidjnelson
even better than manually bootstrapping (which is not always a bad idea either).
甚至比手动引导(这也不总是一个坏主意)更好。
angular.module('myApp', ['app.services'])
.run(function(myservice) {
//stuff here.
});
回答by Ciul
The correct way to achieve that is using resolve property on routes definition: see http://docs.angularjs.org/api/ngRoute.$routeProvider
实现这一目标的正确方法是在路由定义上使用解析属性:请参阅http://docs.angularjs.org/api/ngRoute.$routeProvider
then create and return a promise using the $q service; also use $http to make the request and on response, resolve the promise.
然后使用 $q 服务创建并返回一个承诺;还使用 $http 发出请求并在响应时解决承诺。
That way, when route is resolved and controller is loaded, the result of the promise will be already available and not flickering will happen.
这样,当路由被解析并加载控制器时,promise 的结果将已经可用并且不会发生闪烁。
回答by Guillaume86
As I said in the comments, it would be a lot easier to handle an unloaded state in your controller, you can benefit from $q to make this very straightforward: http://jsfiddle.net/g/g75XQ/4/
正如我在评论中所说,在控制器中处理卸载状态会容易得多,您可以从 $q 中受益,使其变得非常简单:http: //jsfiddle.net/g/g75XQ/4/
if you want to make something in the controller when user is loaded: http://jsfiddle.net/g/g75XQ/6/
如果你想在用户加载时在控制器中做一些事情:http: //jsfiddle.net/g/g75XQ/6/
EDIT: To delay the route change until some data is loaded, look at this answer: Delaying AngularJS route change until model loaded to prevent flicker
编辑:要延迟路由更改直到加载一些数据,请查看此答案:Delaying AngularJS route change until model loaded to prevent flicker
回答by honkskillet
You can use resolve in the .config $routeProvider. If a promise is returned (as it is here), the route won't load until it is resolved or rejected. Also, the return value will be available to injected into the controller (in this case Somert).
您可以在 .config $routeProvider 中使用 resolve。如果返回了一个承诺(就像这里一样),路由将不会加载,直到它被解析或拒绝。此外,返回值将可用于注入控制器(在本例中为 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;
},
},
});
});
回答by Roy Truelove
There are a few ways, some more advanced than others, but in your case ng-hide does the trick. See http://jsfiddle.net/roytruelove/g75XQ/3/
有几种方法,有些比其他方法更先进,但在您的情况下 ng-hide 可以解决问题。见http://jsfiddle.net/roytruelove/g75XQ/3/