AngularJS 与 SignalR

Posted

技术标签:

【中文标题】AngularJS 与 SignalR【英文标题】:AngularJS with SignalR 【发布时间】:2013-12-02 03:09:57 【问题描述】:

我正在使用 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 的作用域系统中。 如何为此编写 jasmine 单元测试用例? 【参考方案1】:

$scope 在此上下文中不存在,因为这是在创建控制器并创建新的子范围时注入的东西。但是,$rootScope 在您需要时可用。

另外,请注意$emit() 向上移动,您的控制器范围不会看到它。您要么需要切换到 $broadcast() 以使事件下降,要么将 $rootScope 也注入到您希望能够订阅 'numberOfIncidents' 的控制器中

查看angular docs 和useful wiki on scopes。

【讨论】:

对于 SignalR 应用程序,我特别推荐 $emit + $rootScope.$on 路径,原因如下:***.com/a/19498009/288703【参考方案2】:

这是一个很好的示例,展示了如何将代理包装在服务中并将$rootScope 用于事件发布/订阅。

http://sravi-kiran.blogspot.com/2013/09/ABetterWayOfUsingAspNetSignalRWithAngularJs.html

【讨论】:

老实说,我会避免这个例子。他使用的服务只有一半的逻辑;另一半($on 订阅者)被烘焙到他的控制器中。 很好,示例的亮点是代理的包装。但是订阅者不会出现在需要他们的任何地方吗?在这个更新 $scope 属性的例子中,逻辑应该去哪里?【参考方案3】:

正如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);
);

【讨论】:

【参考方案4】:

我尝试在更改值后使用 $apply(),我尝试使用 $apply(functuin() value = 3),并且我尝试使用 $emit 和 $broadcast 更改值,但它没有没有帮助。 但是我在控制器中找到了我们需要的 html 解决方案,您可以使用

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

附:我知道这是一个非常古老的问题,但可能像我一样需要这个解决方案。

【讨论】:

以上是关于AngularJS 与 SignalR的主要内容,如果未能解决你的问题,请参考以下文章

AngularJS 学习笔记

Angularjs 1.6.+ 是不是与 jQuery 3.5+ 兼容?

angularJS中XHR与promise

angularJS 事件广播与接收

AngularJS 作用域与数据绑定机制

AngularJs 与Jquery的对比分析,超详细!