Функция вызова контроллера из службы в угловых
Я использую 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
}
}]);