2016-10-31 3 views
0

У меня есть указательная страница index.html с контроллером indexController. Я установил некоторое значение ($ scope.ipAddress) в factory в indexController, которое используется другими контроллерами html внутри ng-view.Выполнение контроллера после выполнения основного контроллера

При загрузке страницы необходимо выполнить сначала indexController, установить значение в factory, а затем это значение используется другими контроллерами страниц внутри ng-view.

Но я думаю, что другие контроллеры выполняются сначала до indexController, и я получаю undefined для значения, которое я установил.

Это indexController с factory:

 angular.module('tollApp') 
.controller('indexController', function($scope,$http,$window,userDetailsFactory){ 
    $scope.usernameFromServer={}; 
    $scope.getUserDetails = function(){ 
     $http({ 
      method:'GET', 
      url:'http://192.168.1.80:4000/getUserDetails' 
      // url:'http://websitename.com/getUserDetails' 
     }) 
     .then(function(response){ 

      // console.log(JSON.stringify(response)); 
      userDetailsFactory.setUserDetailsInFactory(response.data); 
     $scope.usernameFromFactory = userDetailsFactory.getUserDetailsFromFactory().usernameFromSession; 
     $scope.theIP = userDetailsFactory.getUserDetailsFromFactory().ipAddress; 
      // $scope.usernameFromServer = userDetailsFactory.getUserDetailsFromFactory().username; 
      // console.log(JSON.stringify($scope.usernameFromFactory)+"usernameFromFactory"); 
     }) 
    } 
    $scope.logout = function(request,response){ 
     $http({ 
      method:'GET', 
      url:'/logout' 
     }) 
     .then(function(response){ 
      console.log(JSON.stringify(response)); 
      if(response.data=="logout"){ 
       // $window.location.href="http://websitename.comlogin"; 
       $window.location.href="http://192.168.1.80:4000/login"; 

      } 
     }) 
    } 
    console.log("indexController"); 
}).factory('userDetailsFactory',function(){ 
    var user = {}; 
    return { 
     setUserDetailsInFactory : function(val){ 
      user.useridFromSession = val[0].UserID; 
      user.usernameFromSession = val[0].UserName; 
      user.userroleFromSession = val[0].UserRole; 
      user.clientidFromSession = val[0].ClientID; 
      user.ipAddress = "http://192.168.1.80:4000/"; 
      // user.ipAddress = "http://websitename.com/"; 
      // console.log("in set "+user.clientidFromSession); 
     }, 
     getUserDetailsFromFactory : function(){ 
      return user; 
     } 
    }; 
}) 

Другой контроллер, где я использую значение с завода:

$scope.ipForHttp = userDetailsFactory.getUserDetailsFromFactory().ipAddress; 
console.log($scope.ipForHttp); //undefined 
$scope.loading = false; 
$scope.ClientID = userDetailsFactory.getUserDetailsFromFactory().clientidFromSession; 
// $scope.dev={}; 

$scope.getDevice =function(){ 
    console.log($scope.ipForHttp); //undefined 
    $scope.loading = true; 

     $http({ 
     method : "GET", 
     url : $scope.ipForHttp+"getDeviceDetailsReport" 
     }).then(function mySucces(response) { 

ответ

1

Взгляните на ваш $scope.getUserDetails - вы используете $http (docs), чтобы сделать асинхронный вызов AJAX для внешнего сервера.

Функция обратного вызова, которую вы передаете в методе возвращаемого объекта .then(), может быть выполнена когда-то в будущем или может даже не быть - зависит от того, выполняется ли вызов или не выполняется. Вы не должны ожидать, что он будет вести себя синхронно, потому что он никогда не будет, даже если бэкэнд отвечает мгновенно.

Вот почему вы не можете ожидать наличия нужных данных в других контроллерах и вам необходимо соответствующим образом скорректировать код.

// tells angular to execute watcher function on every $digest 
$scope.$watch(function() { 
    // watches the returned value of the service's method 
    return userDetailsFactory.getUserDetailsFromFactory(); 
}, function (newVal) { 
    // filtering out empty object 
    if (!Object.keys(newVal).length) { 
     return; 
    } 

    // the following code will be run when 
    // userDetailsFactory.getUserDetailsFromFactory 
    // returns some value 
    // in our particular case - after getting 
    // data from backend and setting it in 
    // userDetailsFactory.setUserDetailsFromFactory 

    $scope.loading = false; 
    $scope.ipForHttp = newVal.ipAddress; 
    $scope.ClientID = newVal.clientidFromSession; 

    $scope.getDevice(); 
}, 
// tells angular to watch properties of the object too 
true); 

Необязательно, если вам нужно выполнить этот код только один раз, когда пользовательские детали установлены, сделайте это

var unbindUserDetailsWatcher = $scope.$watch(function() { 
    return userDetailsFactory.getUserDetailsFromFactory(); 
}, function (newVal) { 
    if (!Object.keys(newVal).length) { 
     return; 
    } 

    unbindUserDetailsWatcher(); 
    unbindUserDetailsWatcher = null; 

    ... 
}); 
+0

OP, есть гораздо лучший способ решения этой задачи - использование услуг и Promises ([$ q] (https://docs.angularjs.org/api/ng/service/$q), если быть точным). Вы должны взглянуть на документы и примеры и попытаться выяснить это сами. Подсказка - код, который имеет mutliple иждивенцев, должен быть перемещен на сервер. Если вам нужна помощь, просто напишите комментарий, и я покажу вам руководство к правильному решению. –

+0

Это код, который должен перейти в «другой контроллер», я добавлю комментарии к коду, чтобы вам было легче понять. –

+0

«newValue» пуст, когда я 'console.log()'. Это '{}'. Я установил 'timeout' на' indeController' (контроллер, где я установил значение на фабрике). так что он имитирует мою проблему, указанную выше, которая возникает только тогда, когда я принимаю. Когда я удаляю 'timeout', я получаю все значения. – Abhi

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