11

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

.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 
    } 
}); 
+0

[http://stackoverflow.com/questions/20621028/angularjs-calling-a-controller-function-from-a-service][1] [1]: HTTP: //stackoverflow.com/questions/20621028/angularjs-calling-a-controller-function-from-a-service – TechnoCrat

ответ

29

Вы могли бы добиться этого с помощью событий угловые $broadcast или $emit.

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

КОД

.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(); 
    }) 
}); 

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

+0

Благодаря @pankajparkar $ трансляция работала здесь отлично. –

+0

@VinitChouhan cool, рад помочь вам, спасибо :) Happy Coding –

+1

@PankajParkar: Это идеальное решение для моей проблемы. В моем случае контроллеры не были вложенными, и мне пришлось отправить обновление с другого. Его так же, как Рамбан Иладж. –

1

Я знаю, что это старый вопрос, но у меня есть другой вариант. У меня есть личная предвзятость против $ 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 
    } 
}]); 
+0

Зачем добавлять весь контроллер? Просто подпишите определенную функцию. Помните, что если внутри функции изменяется переменная $ scope (или vm), сообщите об изменении в представление с помощью [$ scope.apply в качестве обертки] (http://jimhoskins.com/2012/12/17/angularjs-and -apply.html) –

+0

Хорошие баллы с несколькими предостережениями: а) при регистрации конкретной функции обязательно указывайте, к какому контроллеру она привязана - «SocketService.registerCtrlrFn (this.someFunction.bind (this)» и б) если логика обслуживания уже всегда выполняется как часть цикла дайджеста, обертка $ scope.apply необязательна. Если логика обслуживания не является частью цикла дайджеста, как в исходном вопросе, это необходимо. Если это может быть или не быть в цикле дайджеста, используйте вместо него $ timeout wrapper. – grumpyhoser

+0

Подробнее о [$ scope.apply vs $ timeout] (http://stackoverflow.com/questions/23070822/angular-scope-apply-vs-timeout-as-a-safe-apply) – grumpyhoser

Смежные вопросы