Angular.js Сервисный заводской модуль … возвращает внутренний код как функцию?

#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. Я соответствующим образом изменил код.