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属性时会得到一个未定义的值......奇怪的是,当我登录示波器时,可以看到设置对象......我错过了什么?
更新:我发现了什么,我做错了,是直接从控制器体调用我的方法:
function HomeCtrl($scope, $location, Common) {
...
Common.initChat()
...
}
如果我改变调用被触发点击所有工作正常,但我确实需要此代码来运行页面加载时,什么是正确的方法?
答
几件事情。
- HTTP是异步,这是您的主要问题(安迪敏锐指出)是不推荐
- NG-INIT生产代码,在控制器初始化是更好
- 初始化您scope.settings = { }或者一个体面的默认值可以帮助你,一旦xhr完成,你的设置将可用。
希望这有助于
--Dan
答
这是一个简单的问题,我认为:在$ http调用检索scope.settings之前,您在范围内调用initChat。
+0
感谢您的答复,那是如此......问题是什么是同步的过程中,最好的办法,现在我解决了这个问题在我的根节点上使用ng-init =“initChat()”。不确定这是最好的方式 – 2012-07-09 06:35:17
你能详细说明第二条陈述吗? – 2012-10-05 14:47:43
如果你仔细想想,使用ng-init会污染你的网页和静态内容。如果您在控制器中使用范围变量,那么您最好分离问题。请注意,如果您的javascript函数需要定义值,那么您应该在控制器中分配默认值。我通常创建一个控制器init方法,我称之为控制器的末端。 – 2012-10-08 23:35:54