Функция вызова контроллера из службы в угловых

Я использую socket.io для включения чата в моем приложении, и я использую службу SocketService для выполнения всех файлов сокетов. Когда появилось сообщение, я хочу вызвать функцию контроллера из службы SocketService, чтобы внести некоторые изменения в пользовательский интерфейс. Поэтому я хочу знать, как я могу получить доступ к функции контроллера из службы. Пример кода:

.service('SocketService', function ($http,$rootScope,$q) {
  this.connect = function(){
    var socket = io();
    socket.on('connect',function(){
      // Call a function named 'someFunction' in controller 'ChatController'
    });
  }
});

Это пример кода для службы.

Теперь код для контроллера

.controller('ChatController',function('SocketService',$scope){
  $scope.someFunction = function(){
     // Some Code Here
  }
});

Ответ 1

Это можно сделать с помощью событий angular $broadcast или $emit.

В вашем случае $broadcast было бы полезно, Вам нужно транслировать ваше событие в $rootscope, которое может быть прослушировано всеми дочерними областями, у которых $on с тем же именем события.

CODE

.service('SocketService', function($http, $rootScope, $q) {
    this.connect = function() {
        var socket = io();
        socket.on('connect', function() {
            // Call a function named 'someFunction' in controller 'ChatController'
            $rootScope.$broadcast('eventFired', {
                data: 'something'
            });
        });
    }
});


.controller('ChatController', function('SocketService', $scope) {
    $scope.someFunction = function() {
        // Some Code Here
    }
    $scope.$on('eventFired', function(event, data) {
        $scope.someFunction();
    })
});

Надеюсь, это поможет вам, спасибо.

Ответ 2

Я знаю, что это старый вопрос, но у меня есть другой вариант. У меня есть личная предвзятость против $broadcast - это просто не очень "угловато", я предпочитаю делать явные вызовы в своем коде.

Итак, вместо того, чтобы транслировать на контроллер и запускать другой цикл дайджеста, я предпочитаю, чтобы контроллер регистрировал себя на службе, как показано ниже. Просто будьте осторожны, чтобы не вводить никаких круговых зависимостей, если контроллер использует одну и ту же услугу. Это лучше всего работает с синтаксисом controllerAs, так что вызывающей службе не нужно заботиться о $scope.

Да, это больше кода, чем $broadcast, но он дает общий доступ к сервису для всего контроллера - все его методы и свойства.

.service('SocketService', function ($http,$rootScope,$q) {
  var _this = this;    
  this.chatController = null;
  this.registerCtrlr = function (ctrlr) {
    _this.chatController = ctrlr;
  };
  this.unRegisterCtrlr = function () {
    _this.chatController = null;
  };

  this.connect = function(){
    var socket = io();
    socket.on('connect',function(){
      // Call chatController.someFunction if chatController exists
      if (_this.chatController) {
        _this.chatController.someFunction();
      }
    });
  };
});

.controller('ChatController',['SocketService', '$scope', function(SocketService, $scope){
  SocketService.registerCtrlr(this);
  //-- make sure controller unregisters itself when destroyed - need $scope for this
  $scope.$on('$destroy', function () {
    SocketService.unRegisterCtrlr();
  });
  this.someFunction = function(){
    // Some Code Here
  }
}]);