Служба загрузки AngularJS, затем вызов контроллера и рендеринг
Моя проблема в том, что мне нужен сервис, загруженный до вызова контроллера и визуализации шаблона. 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;
});
6 ответов
Вы можете отложить инициализацию углового приложения, используя ручную инициализацию, вместо автоматической инициализации с помощью 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 и принимает успешный обратный вызов, который запустит угловое приложение.
Также проверьте ngCloak
директива, так как это может быть все, что вам нужно.
Кроме того, при использовании ngRoute вы можете использовать resolve
свойство, для этого вы можете увидеть ответ @honkskillet
Даже лучше, чем загрузка вручную (что тоже не всегда плохая идея).
angular.module('myApp', ['app.services'])
.run(function(myservice) {
//stuff here.
});
Правильный способ добиться этого - использовать свойство resol в определении маршрутов: см. http://docs.angularjs.org/api/ngRoute.%24routeProvider
затем создайте и верните обещание, используя сервис $q; также используйте $http, чтобы сделать запрос, и в ответ разрешите обещание.
Таким образом, когда маршрут разрешен и контроллер загружен, результат обещания будет уже доступен и не будет мерцания.
Как я сказал в комментариях, было бы намного проще обрабатывать незагруженное состояние в вашем контроллере, вы можете воспользоваться $q, чтобы сделать это очень просто: http://jsfiddle.net/g/g75XQ/4/
если вы хотите сделать что-то в контроллере, когда пользователь загружен: http://jsfiddle.net/g/g75XQ/6/
РЕДАКТИРОВАТЬ: Чтобы отложить изменение маршрута до загрузки некоторых данных, посмотрите на этот ответ: Задержка изменения маршрута AngularJS до загрузки модели, чтобы предотвратить мерцание
Вы можете использовать resol в.config $routeProvider. Если обещание будет возвращено (как здесь), маршрут не будет загружен, пока не будет решен или отклонен. Также возвращаемое значение будет доступно для ввода в контроллер (в данном случае 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;
},
},
});
});
Есть несколько способов, некоторые из которых более продвинуты, чем другие, но в вашем случае ng-hide делает свое дело. Смотрите http://jsfiddle.net/roytruelove/g75XQ/3/