AngularJS - 理解作用域

3

我有些困惑,我有一个模块可以路由到不同的控制器:

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属性时会得到undefined值...奇怪的是,当我记录作用域时,我可以看到设置对象...我错过了什么吗?更新:我发现我做错的事情是直接从控制器主体调用我的方法。
function HomeCtrl($scope, $location, Common) {
...
Common.initChat()
...
}

如果把调用改为在点击时触发,一切都正常,但我确实需要在页面加载时运行这段代码。应该采取什么正确的方法?

2个回答

3
我认为这是一个简单的问题:在$scope的$http调用获取$scope.settings之前,你在你的作用域中调用了initChat。

谢谢回复,情况就是这样...问题是什么是最好的同步处理方式,目前我通过在我的根节点上使用ng-init="initChat()"解决了这个问题。不确定这是否是最佳方式。 - Shlomi Schwartz

0

有几件事情需要注意。

  1. http 是异步的,这是你的主要问题(正如 Andy 所指出的)
  2. 不建议在生产代码中使用 ng-init,最好在控制器中初始化
  3. 初始化你的 scope.settings = {} 或一个合适的默认值可能会有所帮助,一旦 xhr 完成,你的设置将可用。

希望这可以帮到你

--丹


你能详细说明第二个声明吗? - ŁukaszBachman
如果您仔细考虑,使用ng-init会污染Web页面并增加静态内容。如果您在控制器中使用作用域变量,则可以更好地分离关注点。请注意,如果您有一个期望定义值的JavaScript函数,则应在控制器中分配默认值。我通常创建一个控制器初始化方法,我会在控制器末尾调用它。 - Dan Doyon

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接