Как стать автором
Обновить

Комментарии 18

Хорошее решение, лучше использования resolve ничего и не придумать.
Разве что можно обойтись без создания дополнительного обещания, а воспользоваться уже тем, которое возвращает $http:
    var checkRouting= function ($q, $rootScope, $location) {
        return !!$rootScope.userProfile || $http.post("/loadUserProfile", { userToken: "blah" })
            .success(function (response) {
                 $rootScope.userProfile = response.userProfile;
            })
            .error(function () {
                $location.path("/");
            });
    };
Спасибо за замечание про обещание из $http. Действительно, если не нужно ничего, кроме загрузки, можно сократить до такого кода. Код в статье предполагает, что возможно нужно посмотреть внутрь данных и на их основе сделать дополнительный редирект, тогда нужен отдельный defered/promise.
success/error обработчики по-идее так же являются deffered объектами, так что они так же могут вернуть какое-то значение, которое в итоге будет заресолвлено. Если же нужно будет зареджектить что-то, то можно просто вернуть $q.reject(). То бишь создавать отдельный promise при любом раскладе не обязательно.
был не совсем прав… лучше так:
var checkRouting= function ($q, $rootScope, $location) {

        return !!$rootScope.userProfile 
               || $http.post("/loadUserProfile", { userToken: "blah" })
                        .error(function () {
                             $location.path('/');
                        })
                        .then(function (response) {
                                $rootScope.userProfile = response.data.userProfile;
                                // тут могла быть ваша пост-обработка данных
                                // если тут нужно зареджектить, то можно вернуть $q.reject()
                
                                return true;
                        });
    };
Тут еще нужно учесть условия на основе самих данных. Написал в апдейте полное решение на цепочках обещаний.
ээээ «раутинг»?
Ну это как с «браузер» вместо «броузер». Хотя согласен, раутинг звучит странно.
Все же русcкоговорящие программисты больше называют это «роутинг».
браузер вполне, раутинг ну прям совсем… хотя блин придираюсь, чувак статью написал в конце концов)
по-русски, вообще, маршрутизация))
Этот комментарий собрал плюсов столько же, сколько сама статья: ) Поменял на роутинг.
Конкретно для поставленной задачи решение отличное, но с ui-router советую разобраться, он прекрасен.
Точно. В ui-router отменить переход можно очень просто:
$scope.$on('$stateChangeStart', function(event, toState, toParams, fromState, fromParams){ 
    if(toState.name==='...' && notAuthorized){
        event.preventDefault();
    }
})
Это удобнее, чем с $routeChangeStart (есть имя стейта), но по сути тот же подход. Как с ui-router заставить переключение стейта ждать, пока не подгрузятся данные с сервера?
Самый простой способ, который сразу приходит в голову, это сделать что-то типа такого:
var process = false;
var auth = function(stateName){
    $http.get('...').success(
        function(data){
            process=true;
           $state.go(stateName);
    });
};
$scope.$on('$stateChangeStart', function(event, toState, toParams, fromState, fromParams){ 
    if(process){
         process=false;
    }else{
        auth(toState.name);
        event.preventDefault();
   }
})

Но скорее всего есть и более элегантные подходы.
Не смотрел resolve стандартного роутера, но в ui-router'е он не работает с вложенными зависимости. Т.е., если в качестве обещания использовать свой сервис, который зависит, например, от $resource, то работать не будет(
А отрезолвить зависимости сервиса в стейте (перед тем, что с промисом на свой сервис) не помогает?
Неа, все варианты перепробовал и через инжектор и так…
Зарегистрируйтесь на Хабре , чтобы оставить комментарий

Публикации