2014-05-08 2 views
5

Вот мой код в сервисе.AngularJS: Как выполнить функцию контроллера ПОСЛЕ завершения вызова AJAX в службе?

this.loginUser = function(checkUser) { 
    Parse.User.logIn(checkUser.username, checkUser.password, { 
     success: function(user) { 
      $rootScope.$apply(function(){ 
       $rootScope.currentUser = user; 
      }); 
     } 
    }); 
}; 

Вот мой код в контроллере:

$scope.logIn = function(){ 
    authenticationService.loginUser($scope.checkUser); 
     console.log($scope.currentUser) 
}; 

Итак, что я хочу сделать это, выполнить некоторый код после завершения AJAX вызова, функция которого успех устанавливает значение $ объема. currentUser, который я могу использовать для некоторой условной логики (например, перенаправления и т. д.) Функция успеха правильно устанавливает значение, но console.log должен быть выполнен ПОСЛЕ выполнения функции authenticationService.loginUser().

ответ

12

Вам необходимо вернуть обещание, используя $q и действовать по этому вопросу.

Например, в вашей службе:

this.loginUser = function(checkUser) { 
    var deferred = $q.defer(); 
    Parse.User.logIn(checkUser.username, checkUser.password, { 
     success: function(user) { 
      $rootScope.$apply(function(){ 
       $rootScope.currentUser = user; 
      }); 
      deferred.resolve(); 
     } 
    }); 
    return deferred.promise; 
}; 

Затем в контроллере действуют на успех:

$scope.logIn = function(){ 
    authenticationService.loginUser($scope.checkUser).then(function() { 
     console.log($rootScope.currentUser)); 
    }); 
}; 
+0

Я попробовал это. Но мой 'console.log ($ scope.currentUser)' все еще не регистрирует новое значение currentUser (задается функцией успеха ajax-вызова в сервисе.) –

+0

Я сделал редактирование. Служба устанавливает текущего пользователя на $ rootScope, контроллер просматривает $ scope.currentUser, и это должно было быть $ rootScope.currentUser. – comradburk

+0

Да! Это сработало! Спасибо :-) Хотя мне было предложено, что использование $ rootScope - это плохая практика. Теперь я пытаюсь реорганизовать свой код, чтобы удалить использование $ rootScope из моей службы. :-) –

2

Попробуйте использовать $rootScope.$broadcast в службе затем прослушивать его в контроллере:

Услуги

Parse.User.logIn(checkUser.username, checkUser.password, { 
    success: function(user) { 
     $rootScope.$apply(function(){ 
      $rootScope.currentUser = user; 
      $rootScope.$broadcast('user.online'); 
     }); 
    } 
}); 

Контроллер

$scope.$on('user.online',function(){ 
    [ DO STUFF HERE ] 
}); 

Это не самый лучший способ сделать это, хотя использование @ comradburk в $ д, вероятно, лучший способ.

0

Если ваше приложение ожидает внешнего результата, вы должны использовать $ q для возврата обещания. Если вы используете компоненты angular-route или ui-router, вы можете использовать параметр resolve. Взгляните на документацию ngRoute. В нем есть пример, основанный на параметре разрешения.

https://docs.angularjs.org/api/ngRoute/service/ $ маршрут

0

я думаю, что у вас есть два варианта здесь

  1. , как ответил comradburk, используйте обещание:

услуг:

this.loginUser = function(checkUser) { 
var deferred = $q.defer(); 
Parse.User.logIn(checkUser.username, checkUser.password, { 
    success: function(user) { 
     deferred.resolve(user); 
    } 
}); 
return deferred.promise; 

};

в контроллере:

$scope.logIn = function(){ 
authenticationService.loginUser($scope.checkUser).then(function(user) { 
    $scope.currentUser = user; 
}); 
}; 
  1. используя решение, разрешить вашу службу на уровне маршрута (... или государственного уровня в случае, если вы используете UI-маршрутизатор) до инициализации контроллера и вставить его в качестве зависимости - полезно в сценариях, таких как аутентификация пользователя, когда вы не хотите, чтобы пользователь мог перемещаться дальше, если аутентификация не удалась.от DOCS https://docs.angularjs.org/api/ngRoute/service/ $ маршруту
0

YOMS (Еще One More Solution):

this.loginUser = function(checkUser, onSuccess) { 
     Parse.User.logIn(checkUser.username, checkUser.password, { 
      success: function(user) { 
       $rootScope.$apply(function() { 
        $rootScope.currentUser = user; 
        if (typeof onSuccess == 'function') onSuccess(user); // optionally pass data back 
       }); 
      } 
     }); 
    }; 

    $scope.logIn = function(user, function(returnedUser) { 
    // console.log(returnedUser); // Optional, The returned user 
     console.log($scope.currentUser) 
    }) { 
     authenticationService.loginUser($scope.checkUser); 
    }; 
+0

для более «углового» способа сделать то же самое, см. @comradburk answer http://stackoverflow.com/a/23546890/572771 – Dementic

Смежные вопросы