0

I am experiencing a strange problem connecting to a hub from a controller when the controller is "inside" a ng-include.

Service:

angular.module('app').service('signalRSvc', function($, $rootScope) {
var proxy = null;

var initialize = function() {
    var connection = $.hubConnection();
    proxy = connection.createHubProxy('myHub');

    connection.start();

    proxy.on('srvMessage', function(data) {
        $rootScope.$emit('newMessage', data);
    });
}

return {
    initialize: initialize
};
});

The Controller:

function MyController($scope, signalRSvc) {

signalRSvc.initialize();

var vm = this;

vm.message = '';

$scope.$parent.$on("newMessage", function (e, data) {
    $scope.$apply(function () {
        vm.mesage = data;
    });
});
}

Index.html (stripped down):

<div data-ng-controller="MyController as vm">
    Server message {{vm.message}}
</div>
<div data-ng-controller="LoginController as vm">
    Server message 2: {{vm.message}}
</div>
<div data-ng-include="'app/layout/shell.html'"></div> 

And Shell.html:

<div data-ng-controller="MyController as vm">
    Server message {{vm.message}}
</div>

Debugging this my service initialize is triggered three times, but serverside OnConnect is only triggered twice. Posting a message to the server the controllers in Index.html is updated, but the one in shell is not. If I remove the controllers from Index.html I get 1 initialize and 0 OnConnect serverside.

However if I drop using a service and put following code inside the controller it get 3 connections and update all controllers:

var hub = $.hubConnection();
var proxy = hub.createHubProxy('myHub');

proxy.on('newMessage', function(data) {
    $scope.$apply(function() {
        vm.message = data;
    });
});

hub.start().done(function () { });

Has anyone else seen this before or can explain why the controller inside ng-incude is not working using the service?

Eebo
  • 49
  • 1
  • 9

1 Answers1

0

I think you might have 2 different issues:

  • you should define your .on handler on the SignalR proxy before calling .start(), this should help solving the missing invocation of OnConnected server side (sounds weird, I know, but try)
  • ngInclude introduces an isolated scope, therefore you have one more level of scopes there, which could introduce an issue. Moreover, in order to send events from parent to child scopes, as you are doing, you should be using $broadcast (check here)

Both are first-impression things I see and you might want to try, I did not do any test though...

Community
  • 1
  • 1
Wasp
  • 3,395
  • 19
  • 37
  • Thanks for your reply. It was two different issues. First one .on handler had to be defined before calling start. And yes it is weird since it is working in the index.html. – Eebo Jun 27 '14 at 08:17
  • Since ngInclude introduced a new isolated scope the eventlistener in my controller would not pick up any messages emited from the service. I personally try to avoid using $broadcast since there might be performance issues with this and instead uses $rootScope as the event bus. Here is a [link](http://jsperf.com/rootscope-emit-vs-rootscope-broadcast) to a test of $emit vs $broadcast – Eebo Jun 27 '14 at 08:33