2015-09-28 2 views
0

Я хочу иметь дело с чатом личных сообщений, поэтому у меня есть 2 услуги:Угловая ручка чат личные сообщения

  • ChatSocket, который подключается к серверу и возвращает сокет
  • ChatHistory, который держит сообщения чата для каждого частного чат сессии в карте

в моей службе ChatSocket я слушаю в чат личных сообщений и добавить их в истории чата:

.factory('ChatSocket', function (ChatHistory) { 
    var socket = io.connect(/* ... */); 
    socket.on('priv_msg', function (data) { 
     ChatHistory.push(data.user, data.msg); 
    }); 
}); 

Я также использовать угловой щий маршрутизатор, так что я могу иметь несколько чатов «окна» таким образом:

.config(function ($stateProvider) { 
    $stateProvider.state('app.chat', { 
     url: '/chat/:uid', 
     views: { 
      'content': { 
       templateUrl: 'templates/chat.html', 
       controller: function ($scope, $stateParams, ChatHistory) { 
        $scope.messages = ChatHistory.get($stateParams.uid); 
        /* 
         This returns an array that looks like: 
         [ 
          { nickname: 'myself', msg: 'hello' }, 
          { nickname: 'someone', msg: 'hi' }, 
          { nickname: 'myself', msg: 'how r u?' }, 
         ] 
        */ 
       } 
      } 
     } 
    } 
}); 

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

Конечно, я мог бы добавить слушателя на «priv_msg» событие в самом контроллере и вызвать $ применять там, но это выглядит немного излишним:

ChatSocket.on('priv_msg', function (data) { 
    if (data.user.id == $stateParams.id) { 
     $scope.$apply(); 
    } 
}); 

Любая идея, как сделать сообщения для обновления ? Мое решение может быть правильным, но я немного нового для углового, поэтому может быть намного лучший способ достичь этого, поэтому я полностью открыт для любых предложений/примеров.

+0

В вашем сервисе нет конкретного контроллера, поэтому нет области действия. вам нужны [события] (https://docs.angularjs.org/api/ng/type/$rootScope.Scope#$emit). – ilj

+0

, поэтому вы имеете в виду излучение события в моем сервисе и прослушивание его в каждом чат-контроллере? Это точно так же, как прослушивание события сокета «priv_msg» в каждом контроллере, не так ли? – Tartuff

+0

не совсем. вы передаете событие, специфичное для пользователя, получившего сообщение. то ваш ChatController знает, какой пользователь владеет им и слушает только события для этого пользователя. или даже пользовательскую комбинацию, если вы хотите иметь несколько окон чата с несколькими другими пользователями. – ilj

ответ

1

делают это изменения:

factory('ChatSocket', function ($rootScope, ChatHistory) { 
    var socket = io.connect(/* ... */); 
    socket.on('priv_msg', function (data) { 
     ChatHistory.push(data.user, data.msg); 
     $rootScope.$broadcast('priv_msg/' + data.user.id, data); 
    }); 
}); 

и

controller: function ($scope, $stateParams, ChatHistory) { 
    $scope.messages = ChatHistory.get($stateParams.uid); 
    // need to set user id to scope for this to work 
    $scope.$on('priv_msg/' + $scope.user.id, function(data) { 
     $scope.messages.push(data); 
    }); 
} 

не тестируется, хотя, может быть опечатка.

+0

yep, ну, я только что протестировал, и он работает, но не нужен '$ scope.messages.push', ему нужна только' $ scope. $ Apply(); 'потому что когда' ChatHistory' обновляется каждый раз или. – Tartuff

+0

отлично. вы можете принять ответ, пожалуйста? – ilj

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