2013-10-10 54 views
0

我想在控制器開始運行之前初始化我的應用程序服務。AngularJS - 在控制器之前初始化服務

我本來以爲我可以先解決一個承諾,返回功能實現這一點:

va.config(['$routeProvider', function($routeProvider) { 
$routeProvider. 
    when('/', {templateUrl: '../partials/home.php', controller: 'VaCtrl',resolve: { 
     pp: vac.loadData 
    }}); 
}]); 


var vac = va.controller('VaCtrl',function($scope,$http,$q,packingProvider){ 
    console.dir(packingProvider.data[2]); 
}); 


vac.loadData = function($http,$timeout,$q,packingProvider){ 

    $http.post('../sys/core/fetchPacking.php').then(function(promise){ 
     packingProvider.data = promise.data; 

    }); 

    var defer = $q.defer(); 
    $timeout(function(){ 
     defer.resolve(); 
    },2000); 
    return defer.promise; 
}; 

然而,控制器仍然在承諾已經解決之前加載,結果我在控制檯大呼小叫

無法讀取屬性未定義

lting '2'。

我在做什麼錯了?

編輯:

此外,該控制器似乎變得與不確定pacingProvider.data對象調用了兩次,第一次,2個secons後一切正常。

回答

3

而不是使用$timeout返回promise的,你可以直接使用$http返回的promise

重寫你的loadData FN這種方式 -

vac.loadData = function($http,$timeout,$q,packingProvider){ 

    var promise = $http.post('../sys/core/fetchPacking.php').then(function(promise){ 
     packingProvider.data = promise.data; 
    }); 

    return promise; 
}; 

閱讀第一線在這裏General Usage部分 - $http promise

此外,resolvemap of dependencies

resolve - {Object。=} - 應該注入控制器的可選依賴關係映射。如果這些依賴關係中的任何一個都是承諾,那麼路由器將等待它們全部被解析或者在控制器被實例化之前被拒絕。

因此,Angular會自動暴露注射圖。所以,你可以做到這一點 -

var vac = va.controller('VaCtrl', function($scope, pp){ 
    // 'pp' is the name of the value in the resolve map for $routeProvider. 
    console.dir(pp[2]); 
}); 
+0

如果您不想使用控制器中的值,則更容易,因爲您可以將結果注入控制器。編輯帖子以添加此示例。我可以編輯你的文章,以便將代碼示例添加到最後? –

+0

雅肯定。希望看到這個例子。 –

+0

它是'pp'還是'dd'? –

3

注意:雖然這會解決您的問題,但this answer可能是正確的解決方案。

服務是總是控制器之前初始化。正如你所說,問題在於你的諾言還沒有結果。最好的選擇就是堅持承諾。

而是露出data對象,暴露的承諾,並使用它:

vac.loadData = function($http,$timeout,$q,packingProvider){ 
    packingProvider.data = $http.post('../sys/core/fetchPacking.php'); 
    return packingProvider.data; 
}; 

而在你的控制,始終高度重視承諾,第一resolval之後,它將獲得在未來打勾解決:

var vac = va.controller('VaCtrl',function($scope,$http,$q,packingProvider){ 
    packingProvider.data.then(function(value) { 
    console.dir(value[2]); 
    }); 
}); 
+0

我不認爲這是需要檢查控制器的承諾。一旦'resolve'中定義的承諾運行完,'$ routeProvider'將只進入控制器。 –

+2

你是對的!你的答案是最好的答案。 –

相關問題