2012-07-08 93 views
3

我很困惑,我有這個模塊,路由到不同的控制器:AngularJS - 理解範圍

var mainModule = angular.module('lpConnect', []). 
    config(['$routeProvider', function ($routeProvider) { 
    $routeProvider. 
     when('/home', {template:'views/home.html', controller:HomeCtrl}). 
     when('/admin', {template:'views/admin.html', controller:AdminCtrl}). 
     when('/connect', {template:'views/fb_connect.html', controller:MainAppCtrl}). 
     otherwise({redirectTo:'/connect'}); 
}]); 

和公共服務,像這樣:

mainModule.factory('Common', ['$rootScope', '$http', function (scope, http) { 
     var methods = { 
      changeLanguage:function (langID) { 
       http.get('JSON/langs/' + langID + '/captions.json').success(function (data) { 
        scope.lang = data; 
       }); 
      }, 
      initChat:function() { 
       console.log(scope); // full object 
       console.log(scope.settings); // undefined 
      } 
     }; 

     //initiate 
     http.get('JSON/settings/settings.json').success(function (data) { 
      scope.settings = data; 
      methods.changeLanguage(scope.settings.lang); 
     }); 


     return methods; 
    }]); 

應用程序加載,並得到(通過XHR)設置對象,我可以看到設置反映在我的DOM。 (例如字幕)

現在,當我從我的HomeCtrl調用initChat方法時,當試圖訪問scope.settings屬性時會得到一個未定義的值......奇怪的是,當我登錄示波器時,可以看到設置對象......我錯過了什麼?

enter image description here

更新:我發現了什麼,我做錯了,是直接從控制器體調用我的方法:

function HomeCtrl($scope, $location, Common) { 
... 
Common.initChat() 
... 
} 

如果我改變調用被觸發點擊所有工作正常,但我確實需要此代碼來運行頁面加載時,什麼是正確的方法?

回答

0

幾件事情。

  1. HTTP是異步,這是您的主要問題(安迪敏銳指出)是不推薦
  2. NG-INIT生產代碼,在控制器初始化是更好
  3. 初始化您scope.settings = { }或者一個體面的默認值可以幫助你,一旦xhr完成,你的設置將可用。

希望這有助於

--Dan

+0

你能詳細說明第二條陳述嗎? – 2012-10-05 14:47:43

+0

如果你仔細想想,使用ng-init會污染你的網頁和靜態內容。如果您在控制器中使用範圍變量,那麼您最好分離問題。請注意,如果您的javascript函數需要定義值,那麼您應該在控制器中分配默認值。我通常創建一個控制器init方法,我稱之爲控制器的末端。 – 2012-10-08 23:35:54

3

這是一個簡單的問題,我認爲:在$ http調用檢索scope.settings之前,您在範圍內調用initChat。

+0

感謝您的答覆,那是如此......問題是什麼是同步的過程中,最好的辦法,現在我解決了這個問題在我的根節點上使用ng-init =「initChat()」。不確定這是最好的方式 – 2012-07-09 06:35:17