AngularJS - 理解范围

问题描述:

我很困惑,我有这个模块,路由到不同的控制器: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() 
... 
} 

如果我改变调用被触发点击所有工作正常,但我确实需要此代码来运行页面加载时,什么是正确的方法?

几件事情。

  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

这是一个简单的问题,我认为:在$ http调用检索scope.settings之前,您在范围内调用initChat。

+0

感谢您的答复,那是如此......问题是什么是同步的过程中,最好的办法,现在我解决了这个问题在我的根节点上使用ng-init =“initChat()”。不确定这是最好的方式 – 2012-07-09 06:35:17