AngularJS与SignalR的结合

13

我正在使用Angular和SignalR进行开发,我试图创建一个服务来充当管理器。

dashboard.factory('notificationsHub', function ($scope) {
  var connection;
  var proxy;

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

    proxy.on('numberOfIncidents', function (numOfIncident) {
      console.log(numOfIncident);
      $scope.$emit('numberOfIncidents', numOfIncident);
    });

    connection.start()
      .done(function() {
        console.log('Connected');
      })
     .fail(function() { console.log('Failed to connect Connected'); });
  };

  return {
    initialize: initialize
  };
});

然而我遇到了错误 Error: Unknown provider: $scopeProvider <- $scope <- notificationsHub

如何使用pubsub将所有通知传递给控制器?也许使用jQuery?


你可以随时来看看我在 Github 上的最新推送:angualr-signalr。它基本上支持原始 Signalr js 客户端所具有的一切功能,而我还添加了一个强大的功能,使其能够将事件正确地传播到 Angular 的作用域系统中。 - Roy Lee
如何编写Jasmine单元测试用例? - Karthik
4个回答

5

$scope在这里的上下文中并不存在,因为它是在控制器创建和新子作用域生成时注入的。但是,$rootScope在您需要时可用。

此外,请注意$emit()是向上传递的,您的控制器作用域将无法看到它。您需要切换到$broadcast(),以便事件向下传递,或者还要将$rootScope注入到您要能够订阅'numberOfIncidents'的控制器中。

请查看Angular文档有关作用域的实用Wiki


特别针对SignalR应用程序,我建议使用$emit + $rootScope.$on路径,原因在此链接中描述得非常好:https://dev59.com/N2gu5IYBdhLWcg3winnU#19498009 - johlrich

3

1
说实话,我会避免使用这个例子。他正在使用一个只有一半逻辑的服务;另一半($on 订阅者)被嵌入到他的控制器中。 - GFoley83
1
好的一点是示例的亮点在于代理的包装。但是订阅者不应该随时随地需要吗?在这个更新$scope属性的示例中,逻辑应该放在哪里? - Jason Capriotti

1
johlrich's answer中所述,$scopeproxy.on内不可用。然而,仅仅切换到$rootScope很可能不起作用。原因是因为使用proxy.on注册的事件处理程序由angular框架外的代码调用,因此angular将无法检测到变量的更改。同样适用于由SignalR事件处理程序广播的$rootScope.$on事件处理程序。有关详细信息,请参见https://docs.angularjs.org/error/$rootScope/inprog

因此,您需要从SignalR事件处理程序中显式地调用$rootScope.$apply()
proxy.on('numberOfIncidents', function (numOfIncident) {
  console.log(numOfIncident);
  $scope.$apply(function () {
    $rootScope.$emit('numberOfIncidents', numOfIncident);
  });
});

或者通过$timeout隐式实现。
proxy.on('numberOfIncidents', function (numOfIncident) {
  console.log(numOfIncident);
  $timeout(function () {
    $rootScope.$emit('numberOfIncidents', numOfIncident);
  }, 0);
});

0

我尝试在改变值后使用$apply(),我尝试使用$apply(function() {value = 3}),还尝试使用$emit和$broadcast来改变值,但都没有帮助。 但我发现我们需要在HTML中找到解决方案,然后在控制器中使用它。

var scope2 = angular.element("#test").scope();
    scope2.point.WarmData.push(result);
    $scope.$apply();

顺便说一句,我知道这是一个非常老的问题,但是像我这样的人可能需要这个解决方案。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接