Javascript 信号器客户端没有';不能在AngularJs控制器内工作

Javascript 信号器客户端没有';不能在AngularJs控制器内工作,javascript,asp.net,angularjs,signalr,signalr.client,Javascript,Asp.net,Angularjs,Signalr,Signalr.client,我已经创建了基于路线的角度应用程序。 在不使用路由的情况下,信号器工作得很好,但是当我使用路由时,信号器只以一种方式工作——从客户端到服务器 <html ng-app="SignalR"> <head> //Scripts <script src="~/signalr/hubs"></script> </head> <body> <a href="#/Today">Today</a> <a hr

我已经创建了基于路线的角度应用程序。 在不使用路由的情况下,信号器工作得很好,但是当我使用路由时,信号器只以一种方式工作——从客户端到服务器

<html ng-app="SignalR">
<head>
//Scripts
<script src="~/signalr/hubs"></script>
</head>
<body>
<a href="#/Today">Today</a>
<a href="#/History">History</a>

<div ng-view>
</div>

<script type="text/javascript">
    var hubConnetion = undefined;
    hubConnetion = $.connection.hubs;
    $.connection.hub.start();


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

    var SignalRApp = angular.module('SignalR', ['ngRoute', 'SignalRControllers']);


    SignalRApp.config(['$routeProvider',
      function ($routeProvider) {
          $routeProvider.
            when('/Today', {
                templateUrl: '@Url.Action("Today","Home")'
            }).
            when('/History', {
                templateUrl: '@Url.Action("History", "Home")'
            })
      }]);

</script>
<script src="~/AngularJs/TodayController.js"></script>
</body>
</html>
Today.html

我不确定,但我认为因为hubConnetion变量包装在控制器中,signlarR找不到它。
有什么angular魔法可以解决这个问题吗?

我对SignalR还是个新手(也是angular的第一次用户),所以我在ASP.NET MVC 4(SignalR 2.2)中重新创建(并简化)了这个项目来解决这个问题。我想不止一个

1) 信号器正在使用JQuery。在jQuery(以及几乎任何其他JS框架)中,最好在“文档就绪”事件之后执行代码。所以我在jQuery文档就绪处理程序中包装了信号器设置(请参见下面的代码)。 此外,我删除了
hubConnetion
全局变量,因为全局变量是坏的+在jQuery文档就绪处理程序中包装后,变量是该处理程序的本地变量,并且无论如何在控制器代码中都无法访问

2) 主要问题是什么(部分):

通常在调用start方法之前注册事件处理程序 建立联系。如果你想注册一些事件 在建立连接之后,您可以这样做,但是 在调用之前,必须注册至少一个事件处理程序 启动方法。这样做的一个原因是,一个网络中可能有许多集线器 应用程序,但您不希望在 如果您只打算使用其中一个,则每个集线器。当 连接建立后,集线器上的客户端方法的存在 代理是通知信号器触发OnConnected事件的内容如果你 在调用start方法之前不要注册任何事件处理程序,否则 将能够调用集线器上的方法,但集线器的未连接 方法,并且不会从 服务器

您的事件处理程序是在控制器工厂方法中设置的,该方法的调用要比连接
start()
方法晚得多。 尝试在调用
start()
之前添加临时处理程序,如下所示:

$.connection.tasklistHub.client.getTask=function(){}

3) 为了确保问题出在信号器而不是角度,我同时打开了服务器端和客户端。完成上述所有更改后,在客户端上成功接收到来自服务器的事件:

signar:在hub“TasklistHub”上触发客户端hub事件“getTask”

但Angular未能使用收到的数据更新div。解决方案是使用中提到的
$rootScope.$apply
函数。现在一切正常。请参阅下面的完整代码

旁注:我知道这只是示例代码。在任何真实世界的项目中,我都会考虑在上面提到的服务中使用客户端的信号包,或者使用(看起来非常优雅)

我还收回了之前关于客户端处理程序名称的回答,因为根据同一文档,客户端方法名称匹配不区分大小写

Index.cshtml


您的解决方案是完美的,对于那些即使在讲座结束后仍面临此问题的人,有一个简单的解决方案可以在应用程序的每个部分从服务器到客户端获得响应:

    angular.module('groupApp').run(function ($rootScope, chat) {
        $rootScope.messages = [];
        chat.client.newMessage = function onNewMessage(message) {
           $rootScope.messages.push({ message: message });
           $rootScope.$apply();
    };
});
在您看来,您可以在任何地方使用“消息”数组:

 <div ng-repeat="m in messages">
        {{m.message}}
 </div>

{{m.message}}

错误消息是什么。有吗?打开Firebug或Chrome开发者工具窗口,查看控制台消息。尝试添加此
$.connection.hub.logging=true;$.connection.hub.error(函数(error){console.error('signarerror:'+error);})
$.connection.hub.start()之前我添加了您的代码,但没有错误消息,而且如果我开始调试,当我单击调用SendTask时,它会像预期的那样进入中心函数,但在
Clients.All.GetTask(Name)之后什么都没有发生,
hubConnetion.client.getTask=function(Task)
永远不会被调用,服务器的响应会传递到浏览器吗?(参见浏览器开发工具中的“网络”选项卡)没有响应,但之后我将
hubConnetion.client.getTask=function(Task)
,只有像这样的post方法
send?transport….
它可能与Angular运行控制器构造函数的方式有关。我不是角度方面的专家,所以我帮不了你。我建议大家看一看关于如何将信号器与Angular(像这样)结合使用的教程,或者请在Today.html中添加所有代码,而不仅仅是控制器。没有更多的代码了,就这样
public class Hubs: Hub
{
   public void SendTask(string Name)
   {
      Clients.All.GetTask(Name);
   }
}
<html lang="en" ng-app="SignalR">
    <head>
        <meta charset="utf-8" />
        <title>SignalR & AngularJS</title>
        <script src="~/Scripts/jquery-1.6.4.js"></script>
        <script src="~/Scripts/jquery.signalR-2.2.0.js"></script>
        <script src="~/signalr/hubs"></script>
        <script src="~/Scripts/angular.js"></script>

        <script type="text/javascript">
            $(function() {
                $.connection.hub.logging = true;

                // temporary handler to force SignalR to subscribe to server events
                $.connection.tasklistHub.client.getTask = function () { };

                $.connection.hub.start().done(function () {
                    $('#connectionStatus').text('Connected');
                    console.log('Now connected, connection ID =' + $.connection.hub.id);
                });
            });

            var SignalRControllers = angular.module('SignalRControllers', []);
            var SignalRApp = angular.module('SignalR', ['SignalRControllers']);
        </script>
        <script src="~/Scripts/app/TodayController.js"></script>
    </head>
<body>
    <div id="body">
        <div ng-view>
            <div ng-controller="TodayController">

                <div id="connectionStatus"></div>

                <div>{{Task}}</div>

                <input id="taskName" type="text"/>
                <input type="button" name="Send Task" value="Send Task" data-ng-click="sendTask()" />
            </div>
        </div>
    </div>
</body>
</html>
SignalRControllers.controller('TodayController', [
        '$scope', '$http', '$rootScope',
        function ($scope, $http, $rootScope) {
            $scope.sendTask = function() {
                $.connection.tasklistHub.server.sendTask($("#taskName").val());
            };
            $scope.Task = "Empty";

            $.connection.tasklistHub.client.getTask = function (task) {
                console.log(task);
                $rootScope.$apply(function () {
                    $scope.Task = task;
                });             
            };
        }
    ]
);
    angular.module('groupApp').run(function ($rootScope, chat) {
        $rootScope.messages = [];
        chat.client.newMessage = function onNewMessage(message) {
           $rootScope.messages.push({ message: message });
           $rootScope.$apply();
    };
});
 <div ng-repeat="m in messages">
        {{m.message}}
 </div>