При использовании Angular с SignalR, как я могу уведомить контроллер, когда в объект вносится изменение?

0

У меня есть достаточно простое приложение с угловыми элементами с четырьмя контроллерами и двумя службами. Один сервис хранит данные и делится ими с другими контроллерами, примерно так:

var DataService = function($http) {
    this.testData = [];
}    
MyApp.service('DataService', ["$http", DataService]);

а другая служба содержит методы SignalR на стороне клиента, что-то вроде этого:

var HubService = function(DataService) {    
    this.testHub = $.connection.TestHub;
    this.connectionStatus = [];

    this.connectToHub = function(callback) {
        var self = this;
        $.connection.hub.start().done(function() {
            self.connectionStatus.push(1);
            if (callback) {
                callback();
            }
        });
    };  

    this.getSomeData = function (node, callback) {        
        this.testHub.server.getSomeData(node).done(function (response) {            
            if (callback) { callback(); }         
        });
    };  

    this.testHub.client.addData = function(serverData) {
        DataService.testData.push(serverData)   
    };  
}

MyApp.service('HubService', ["DataService", HubService]);

где серверный метод-хаб - это что-то вроде

public class TestHub : Hub {
     public void GetSomeData(Node node) {
        var data = _queries.getSomeDataFromAServer();
        Clients.All.addData(data);
     }
}

Теперь все работает отлично, я вставляю DataService и HubService в контроллеры, и я могу вызвать метод HubService.getSomeData(), который вызывает метод на стороне сервера, а затем вызывает клиентский метод SignalR и DataService. Объект testData обновляется.

Проблема в том, что контроллеры не уведомляются об этом изменении до следующего цикла $ digest, который обычно является своего рода событием пользовательского интерфейса. Мне нужно, чтобы контроллеры были немедленно уведомлены. Я знаю, что обычно я могу просто вызвать $ scope. $ Apply() для ручного запуска цикла $ digest, но поскольку метод службы вызывается непосредственно из метода на стороне сервера, нет возможности использовать $ scope.

Что я делаю? Как заставить Angular смотреть объект службы для изменений с другой службы или как я могу вызвать цикл $ digest для всех контроллеров из сервис-метода?

Теги:
signalr

1 ответ

1
Лучший ответ

Это может быть не ответ, но вы получаете механизм, как вы его достигаете.

var app = angular.module('plunker', []);

app.service('myService', function($rootScope) {
  var data = 0;
  var id = 0;

  var increment = function() {
    data = data + 1;
    $rootScope.$apply();
    console.log("Incrementing data", data);
  };

  this.start = function() {
    id = setInterval(increment, 500) ;

  };

  this.stop = function() {
    clearInterval(id);
  };

  this.getData = function() { return data; };

}).controller('MainCtrl', function($scope, myService) {
  $scope.service = myService;
  $scope.controllerData = 0;

  $scope.start = function() {
    myService.start();
  };

  $scope.stop = function() {
    myService.stop();
  };

  $scope.$watch('service.getData()', function(newVal) {

    console.log("New Data", newVal);
    $scope.controllerData = newVal;
  });
});
  • 0
    Вы можете использовать apply для явного вызова цикла.
  • 0
    Так что бывают случаи, когда Angular жалуется на $ scope. $ Apply (), говоря, что цикл $ digest уже запущен. Я исправляю это, оборачивая его, если (! $ Scope. $$ phase) {$ scope. $ Apply ();}. Должен ли я сделать какой-то эквивалент с $ rootScope?

Ещё вопросы

Сообщество Overcoder
Наверх
Меню