AngularJS没有在控制器中接收广播

时间:2015-07-18 15:42:12

标签: javascript angularjs

我正在处理基本的HTML游戏,我有以下页面(不包括普通的HTML和Angular.js):

<div id="gameContainer" ng-controller="gameController">
    <div id="gameHead">
        <!-- Head bar -->
    </div>
</div>

<div id="debugContainer" ng-controller="debugController">
    <ul id="debugList">
        <li ng-repeat="log in logs">
            <span class="logTime">{{ log.time }}:</span> {{ log.message }}
        </li>
    </ul>
</div>

我在HTML文档的末尾定义了三个JS文件:

app.js:

var game = angular.module('mystikApp', []);

debugController.js:

game.controller('debugController', ['$rootScope', '$scope', function($rootScope, $scope){
    // Log element
    $scope.logs = [];

    // Padding
    var padZeros = function(i) {
        if (i < 10) {
            i = "0" + i;
        }
        return i;
    }

    $scope.$on('helloWorld', function(e, args){
        alert(args.message);
    });

    // Add a new log entry
    $scope.addLogEntry = function(msg){
        var d = new Date();
        var hour = d.getHours();
        var min = d.getMinutes();
        var time = padZeros(hour) + ':' + padZeros(min);

        var newEntry = {
            message: msg,
            time: time
        };

        $scope.logs.push(newEntry);
    }

    $scope.$on('addLogEntry', function(e, args){
        $scope.addLogEntry(args.message);
        alert('Log entry added, msg: ' + args.message);
    });
}]);

gameController.js:

game.controller('gameController', ['$rootScope', '$scope', function($rootScope, $scope){
    $rootScope.$broadcast('addLogEntry', {message: 'Welcome!'});

    $scope.$emit('helloWorld', {message: 'Hello World!'});
}]);

JS文件按照上面列出的顺序加载,第二个helloWorld发出&#39;事件只是试图让这个工作。

问题

因此,当游戏加载(gameController.js文件)时,我想记录一条消息,例如“游戏加载”和“#39;到日志框。出于某种原因,似乎调试控制器从未收到过该事件,并且我已查看了有关$broadcast$emit的使用的所有代码示例,并且我已经查看了难以理解为什么现在还没有工作。

我见过一些人建议使用服务代替这一点,但我宁愿坚持广播。

2 个答案:

答案 0 :(得分:2)

我在阅读你的评论后删除了我原来的全部答案:)

如果您将代码应用于ng-click事件,那么您现在可以正常运行的代码。

我看到你想要的是当页面加载到$broadcast事件时。使用当前代码的问题是$broadcasts没有被捕获,因为所有内容(无论它是什么)都没有完全加载。

AngularJS嵌入了jqLite:jQuery功能的一小部分。它恰好实现了在完全加载DOM时触发的ready()事件。

这是我的建议:

game.controller('gameController', ['$rootScope', '$scope', function($rootScope, $scope){
    angular.element(document).ready(function () {
        $rootScope.$broadcast('addLogEntry', {message: 'Welcome!'});
        $scope.$apply();
    });
}]);

你必须使用$scope.$apply(),否则当你$scope.addLogEntry时,什么都不会发生。这是因为ready()是jqLit​​e事件而不是AngularJS事件。 $scope.$apply()将强制摘要周期运行并更新您的范围。

答案 1 :(得分:0)

这是你的问题。 创建控件宽度时,会创建一个新的$ scope。 新的$ scope是$ rootScope的子节点。

知道我们可以说$ broadcast会从上到下发送事件,$ emmit从下到上发送。

因此,如果您想要在同一级别传递控件,则必须从父级别进行$ broadcast。

public static boolean isPortrait(View v){
        if(v.getResources().getConfiguration().orientation == 1)
            return true;
        return false;
    }