#javascript #angularjs
#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. К моменту отправки вашего первого события контроллер еще не создан. Вы можете провести рефакторинг своего приложения. запустите фабрику, которая предоставила данные, и просмотрите данные с вашего контроллера. Я понимаю, что это иронично, потому что я изначально рекомендовал вам сменить фабрику на app.run.
Ответ №1:
К моменту отправки вашего первого события контроллер еще не создан. Вы можете реорганизовать приложение, запустить его на фабрике, которая предоставляет данные результата, а затем просмотреть данные с вашего контроллера:
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 = resu<
});
//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);
});
});
Комментарии:
1. Любопытно… почему я не мог сохранить .run() и сделать
$timeout(function(){$rootScope.$broadcast('$cpuResult', result); }, 1000);
? Я попытался сохранить .run() и таким образом, и, конечно, не сработало.2. Вы имеете в виду $timeout(function(){$rootScope.$broadcast(‘$cpuResult’, результат);}, 1000); ? Мне кажется, что это, вероятно, сработает для меня, если ваша страница не слишком сложная, но я думаю, что использование $ watch более идиоматично.
3. Вы можете поместить сообщение журнала в инициализацию вашего контроллера и сообщение журнала в вашу трансляцию, чтобы проверить, что контроллер создан до отправки первого события.
4. Почему я не смог внедрить свой сервис как
.controller('cpuCtrl', ['sseHandler', function($scope) {}]);
?5. Это должно выглядеть как .controller(‘cpuCtrl’, [‘$scope’, ‘sseHandler’, функция ($scope, sseHandler) {}]);