当页面加载时,Angular.js $ scope.on()没有捕获第一个广播

时间:2014-06-29 01:23:54

标签: javascript angularjs

出于某种原因......当页面首次加载时$scope.$on('$cpuResult', cpuUpdate);没有捕获第一个广播。我确认第一次广播与console.log("broadcast");成功结束。第一次广播对于初始化数据很重要,$scope.$on('$cpuResult', cpuUpdate);怎么没有捕获第一个广播,我该如何解决这个问题?

angular.module('monitorApp')
.controller('cpuCtrl', function($scope) {
    $scope.avaiable = "";
    $scope.apiTimeStamp = "";
    $scope.infoReceived = "";
    $scope.last15 = "";
    $scope.last5 = "";
    $scope.lastMinute = "";

    var cpuUpdate = function (e, result) {
        console.log("yay");
        $scope.$apply(function () {
            $scope.available = result.cpuResult.avaiable;
            $scope.apiTimeStamp = result.cpuResult.timestamp;
            $scope.infoReceived = new Date();
            $scope.last15 = result.cpuResult.metrics['15m'].data
            $scope.last5 = result.cpuResult.metrics['5m'].data
            $scope.lastMinute = result.cpuResult.metrics['1m'].data
        });
    }
    $scope.$on('$cpuResult', cpuUpdate);
});

angular.module('monitorApp')
.run(function ($rootScope) {
    var source = new EventSource('/subscribe');

    source.addEventListener('message', function(e) {
        var result = JSON.parse(e.data);
         event = Object.keys(result)[0];
         switch(event) {
             case "cpuResult":
                 console.log("broadcast");
                 $rootScope.$broadcast('$cpuResult', result);
             break;
         }
    });
});

<script src="scripts/angularApp.js"></script>
<script src="scripts/controllers/main.js"></script>
<script src="scripts/services/sse_listen.js"></script>

1 个答案:

答案 0 :(得分:3)

当您的第一个事件被推出时,尚未创建控制器。您可以将应用程序运行重构为公开结果数据的工厂,然后从控制器中查看数据:

angular.module('monitorApp').
factory('sseHandler', function ($timeout) {
    var sseHandler = {};
    sseHandler.result = {};
    var source = new EventSource('/subscribe');
    source.addEventListener('message', function(e) {
        var result = JSON.parse(e.data);
         event = Object.keys(result)[0];
         switch(event) {
             case "cpuResult":
                 console.log('sseHandler result change');
                 //The controller will watch the result
                 //on this object
                 $timeout(function(){
                     sseHandler.result = result;
                 });
                 //I wrap the result change in a timeout
                 //to schedule an apply,
                 //which will trigger your watches to run
                 //their dirty checks.
             break;
         }
    });
    return sseHandler; //return the object with exposed result
}).
controller('cpuCtrl', function($scope, sseHandler) {
    $scope.avaiable = "";
    $scope.apiTimeStamp = "";
    $scope.infoReceived = "";
    $scope.last15 = "";
    $scope.last5 = "";
    $scope.lastMinute = "";

    var cpuUpdate = function (result) {
        console.log("yay");
        // You don't need the apply here anymore.
        $scope.available = result.cpuResult.avaiable;
        $scope.apiTimeStamp = result.cpuResult.timestamp;
        $scope.infoReceived = new Date();
        $scope.last15 = result.cpuResult.metrics['15m'].data;
        $scope.last5 = result.cpuResult.metrics['5m'].data;
        $scope.lastMinute = result.cpuResult.metrics['1m'].data;
    }
    // The second argument of the watch gets called when
    // the result of the first argument changes
    // I'm assuming timestamp changes often enough
    $scope.$watch(function(){ 
        return sseHandler.result.timestamp; 
    }, function(){
        cpuUpdate(sseHandler.result);
    });

});