#javascript #angularjs
#javascript #angularjs
Вопрос:
Я действительно новичок в angular.js . Это мой первый сервис, который я написал. Он принимает объект json и обновляет область действия контроллера. Я немного смущен этим…Я думаю, что я должен обернуть внутренний код sseListener и вернуть его как функцию, но я не уверен, как именно я бы это написал и почему мне нужно возвращать его как функцию.
Кроме того, если я введу эту службу в несколько контроллеров, это увеличит количество прослушивателей событий? Я хочу иметь только один прослушиватель событий.
one@demo ~/cloudimageshare-monitoring/project/app/scripts $ cat services/sse_listen.js
angular.module('monitorApp')
.factory('sseListener', function () {
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":
cpuUpdate(result);
break;
}
});
}
one@demo ~/cloudimageshare-monitoring/project/app/scripts $ cat controllers/main.js
'use strict';
angular.module('monitorApp')
.controller('homeCtrl', function($scope, $location, $document) {
console.log("s");
});
angular.module('monitorApp')
.controller('cpuCtrl', function($scope) {
$scope.apiTimeStamp = "";
$scope.infoReceived = "";
$scope.last15 = "";
$scope.last5 = "";
$scope.lastMinute = "";
var cpuUpdate = function (result) {
$scope.$apply(function () {
$scope.apiTimeStamp = result.cpuResult.timestamp;
$scope.infoReceived = new Date();
$scope.last15 = result.cpuResult.metrics['1m'].data
$scope.last5 = result.cpuResult.metrics['5m'].data
$scope.lastMinute = result.cpuResult.metrics['15'].data
});
}
});
Ответ №1:
Вместо прямого вызова cpuUpdate (мне непонятно, как ваша фабрика получает ссылку на эту функцию), было бы лучше использовать $rootScope. $broadcast(eventName, data) и реагировать на событие в вашем контроллере. Кроме того, вы должны возвращать объект с фабрик, но поскольку вам не нужно вводить это куда-либо, лучше всего поместить его в app.run. Вот как, я думаю, должен выглядеть ваш код с упомянутыми мной изменениями:
angular.module('monitorApp').
run(function ($rootScope) { //Inject the $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":
// Broadcast the event with data
$rootScope.$broadcast('$cpuResult', result);
break;
}
});
}).
controller('cpuCtrl', function($scope)){
$scope.apiTimeStamp = "";
$scope.infoReceived = "";
$scope.last15 = "";
$scope.last5 = "";
$scope.lastMinute = "";
// Need to pass the event to cpuUpdate,
var cpuUpdate = function (e, result) {
$scope.$apply(function(){
$scope.apiTimeStamp = result.cpuResult.timestamp;
$scope.infoReceived = new Date();
$scope.last15 = result.cpuResult.metrics['1m'].data
$scope.last5 = result.cpuResult.metrics['5m'].data
$scope.lastMinute = result.cpuResult.metrics['15'].data
});
};
//Listen for the event, call cpuUpdate when caught
$scope.$on('$cpuResult', cpuUpdate);
});
Комментарии:
1. Это связано с возвратом объекта с моей фабрики? Я не вижу возвращаемого имени функции в sseListener
2. Упс, я забыл эту часть, я это исправлю.
3.О … хорошо…Я бы не хотел возвращаться
var source = new EventSource('/subscribe');
source.addEventListener('message', function(e) {}
? если нет, то почему?4. Вам нужно только вернуть объект, предоставляющий доступ к элементам, к которым вы хотите получить доступ, в любом случае вводя фабрику. Возможно, вам захочется вернуть {‘source’: source}, чтобы вы могли проверить статус прослушивателя событий.
5. На самом деле, если подумать, поскольку вы нигде не вводите это, я думаю, что лучше всего поместить этот код в app.run, а не в factory. Я соответствующим образом изменил код.