2015-05-27 53 views
0

我有我的控制器和服務這樣的(都在單獨的文件)中:AngularJS如何事件偵聽器後更新視圖/範圍

.controller('authCtrl',['$scope','MyConnect',function($scope,MyConnect){ 
     /***************Testing Area******************/ 
     console.log("connecting"); 
     MyConnect.initialize(); 
     $scope.myID = ??? //I want this to be updated 
} 


.factory('MyConnect', ['$q', function($q) { 
    var miconnect = { 
     initialize: function() {   
      this.bindEvents(); 
     }, 

     bindEvents: function() { 
      document.addEventListener('deviceready', this.onDeviceReady, false);    
     }, 

     onDeviceReady: function() { 
      thirdPartyLib.initialize(); 
      miconnect.applyConfig(); 
     },  

     applyConfig: function() { 
       if (thirdPartyLib.isReady()) { 
        //I want in here to update $scope.myID in controller and reflect the changes in UI textbox 
        //$scope.myID = thirdPartyLib.id(); //something like this will be good 
       } 
       else { 
       } 
     } 
    } 

    return miconnect; 
}]) 

所以,我不知道如何更新$ scope.myID (這是一個文本框)。我不確定如何在事件監聽器之後執行回調。通常,如果我可以使用ajax,然後等待數據到達。

主要的是,我需要使用第三方庫(專有),並且基於指南,在設備準備好之後調用thirdPartyLib.initialize(),然後在實際調用之前檢查thirdPartyLib.isReady函數來檢索id。

回答

2

在服務準備就緒之前,您不能直接指定$scope.myID。您需要以某種方式提供回撥,將正確的值分配給您的$scope型號。你可以通過使服務返回一個Promise來解決它的準備就緒,或者通過從服務中發出一個事件來做到這一點。我將舉出最後一個選項的例子。根據thirdPartyLibangular的集成程度,您可能需要踢angular才能正確應用範圍。這裏我使用$scope.$evalAsync。您也可以返回一個承諾,通過id解決,而不是像直接使用ajax庫那樣直接將回調傳遞給.then

而且,如果thirdPartyLib特別蘇茨基,它的初始化是異步的,並且它不爲你提供任何回調/承諾/事件驅動的指標,它的準備,你可能需要

.controller('authCtrl', ['$scope', 'MyConnect', 
 
    function($scope, MyConnect) { 
 
    console.log("connecting"); 
 
    // my connect should probably just `initialize()` on it's own when it's created rather than relying on the controller to kick it. 
 
    MyConnect.initialize(); 
 
    MyConnect.whenID(function(id) { 
 
     // $evalAsync will apply later in the current $digest cycle, or make a new one if necessary 
 
     $scope.$evalAsync(function(){ 
 
     $scope.myID = id; 
 
     }); 
 
    }) 
 
    } 
 
]) 
 

 
.factory('MyConnect', ['$q', '$rootScope' 
 

 
    function($q, $rootScope) { 
 
    var miconnect = { 
 
     ..., 
 

 
     onDeviceReady: function() { 
 
     thirdPartyLib.initialize(); 
 
     miconnect.applyConfig(); 
 
     /* Also, if the `thirdPartyLib` is particularly sucky, AND if it's initialize is asynchronous, 
 
     * AND it doesn't provide any callback/promise/event driven indicator that it's ready, 
 
     * you may need to hack some kind of `setTimeout` to check for when it is actually `isReady`. */ 
 

 

 
     // ok, listeners can do stuff with our data 
 
     $rootScope.$emit('MyConnect.ready'); 
 
     }, 
 

 
     whenID: function(callback) { 
 
     if (thirdPartyLib.isReady()) { 
 
      callback(thirdPartyLib.id); 
 
     } else { 
 
      var unregister = $rootScope.$on('MyConnect.ready', function() { 
 
      // unregister the event listener so it doesn't keep triggering the callback 
 
      unregister(); 
 
      callback(thirdPartyLib.id); 
 

 
      }); 
 
     } 
 
     } 
 
    } 
 

 
    return miconnect; 
 
    } 
 
])