【问题标题】:AngularJS - understanding scopesAngularJS - 理解范围
【发布时间】:2012-07-08 12:32:18
【问题描述】:

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

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()
...
}

如果我将调用更改为单击触发,一切正常,但我确实需要在页面加载时运行此代码,正确的方法是什么?

【问题讨论】:

    标签: javascript model-view-controller scope angularjs


    【解决方案1】:

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

    【讨论】:

    • 感谢您的回复,原来如此......问题是同步进程的最佳方式是什么,现在我用 ng-init="initChat()" 解决了这个问题我的根节点。不确定这是最好的方法
    【解决方案2】:

    几件事。

    1. http 是异步的,这是您的主要问题(正如 Andy 敏锐地指出的那样)
    2. ng-init 不推荐用于生产代码,在控制器中初始化更好
    3. 初始化您的 scope.settings = {} 或适当的默认值可能会对您有所帮助,一旦 xhr 完成,您的设置将可用。

    希望对你有帮助

    --丹

    【讨论】:

    • 您能否详细说明第二个声明?
    • 如果你仔细想想,使用 ng-init 会用静态内容污染你的网页。如果您在控制器中使用范围变量,那么您最好分离关注点。请注意,如果您有期望定义值的 javascript 函数,那么您应该在控制器中分配默认值。我通常会创建一个控制器 init 方法,在控制器结束时调用该方法。
    猜你喜欢
    • 2014-12-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-24
    • 1970-01-01
    • 2014-09-29
    相关资源
    最近更新 更多