11

Używam socket.io, aby włączyć czat w mojej aplikacji i używam usługi SocketService, aby wykonać wszystkie czynności związane z gniazdem. Kiedy przyszedł komunikat, chcę wywołać funkcję kontrolera z usługi SocketService, aby wprowadzić pewne zmiany w interfejsie użytkownika. Więc chcę wiedzieć, w jaki sposób mogę uzyskać dostęp do funkcji kontrolera z usługi. Przykładowy kod:Funkcja kontrolera połączeń z usługi w 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' 
    }); 
    } 
}); 

To jest przykładowy kod dla usługi.

Teraz kod regulatora

.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

Odpowiedz

29

Można by to osiągnąć za pomocą kątowe Wydarzenia $broadcast lub $emit.

W twoim przypadku $broadcast byłoby pomocne, Trzeba transmitowane wydarzenie w $rootscope że można słuchać przez wszystkich zakresów dziecko, które ma $on z samej nazwie zdarzenia.

KOD

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

Nadzieja to może pomóc, dzięki.

+0

Dzięki @pankajparkar $ broadcast działało tu doskonale. –

+0

@VinitChouhan cool, Cieszę się, że Ci pomogłem, dzięki :) Happy Coding –

+1

@PankajParkar: To idealne rozwiązanie również dla mojego problemu. W moim przypadku kontrolery nie były zagnieżdżone i musiałem wysłać aktualizację z drugiej. To tak jak Ramban Ilaaj. –

1

Wiem, że to stare pytanie, ale mam inną opcję. Mam osobistą stronniczość przeciwko emisji w USD - po prostu nie czuję się bardzo "kanciasto", wolę wykonywać wyraźne połączenia w moim kodzie.

Więc zamiast rozgłaszać do kontrolera i uruchamiać kolejny cykl trawienny, wolę, aby kontroler rejestrował się w usłudze, jak poniżej. Uważaj, aby nie wprowadzać żadnych zależności kołowych, jeśli kontroler korzysta z tej samej usługi. Działa to najlepiej w przypadku składni kontrolera, więc usługa wywołująca nie musi dbać o zakres $.

Tak, jest to kod bardziej niż $ broadcast, ale daje on usłudze pełny dostęp do całego kontrolera - wszystkie jego metody i właściwości.

.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

Dlaczego dodać cały kontroler? Po prostu zapisz konkretną funkcję. Pamiętaj, że jeśli wewnątrz funkcji zmieniony jest $ scope (lub vm), powiadom zmiany do widoku za pomocą [$ scope.apply jako opakowania] (http://jimhoskins.com/2012/12/17/angularjs-and -apply.html) –

+0

Dobre punkty, z kilkoma zastrzeżeniami: a) podczas rejestrowania określonej funkcji, należy wskazać kontroler, do którego jest przypisana - "SocketService.registerCtrlrFn (this.someFunction.bind (this)", oraz b) jeśli logika usług jest już zawsze uruchamiana jako część cyklu podsumowania, opakowanie $ scope.apply nie jest konieczne. Jeśli logika usługi nie jest częścią cyklu podsumowania, tak jak w pytaniu oryginalnym, jest to konieczne. Jeśli może, ale nie musi, być w ramach cyklu podsumowania, użyj zamiast tego opakowania $ timeout. – grumpyhoser

+0

Więcej informacji na temat [$ scope.zastosuj vs $ timeout] (http://stackoverflow.com/questions/23070822/angular-scope-apply-vs-timeout-as-a-safe-apply) – grumpyhoser

Powiązane problemy