问题描述
我已经创建了一个基于角航线申请。
如果不使用航线,Signalr工作正常,但是当我的路线工作,Signalr工作只是以一种方式 - 从客户端到服务器
I've created Angular application based on routes.Without using the routes, the Signalr works fine, but when I work with routes, the Signalr works just in one way - from client side to server.
<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>
的 TodayController.js 的
SignalRControllers.controller('TodayController', ['$scope', '$http',
function ($scope, $http) {
$scope.sendTask = function () {
hubConnetion.server.sendTask($("#taskName").val());//works
}
$scope.Task = "task1";
hubConnetion.client.getTask= function (Task) {//never invoked
$scope.Task = Task;
}
}]);
的 Today.html 的
<div ng-controller="TodayController">
<div>{{Task}}</div>
<input id="taskName" type="text" />
<div ng-click="sendTask()">SendTask</div>
</div>
的 Hubs.cs 的
public class Hubs: Hub
{
public void SendTask(string Name)
{
Clients.All.GetTask(Name);
}
}
我不知道,但我认为这是因为的 hubConnetion 的变量被包裹在控制器内,signlarR找不到它。
是否有任何角度魔法可以解决这个?
I'm not sure, but I think that because the hubConnetion variable is wrapped inside the controller, signlarR couldn't find it.Is there any angular magic that can solve this ?
推荐答案
我也相当新的SignalR(与第一次角的用户),所以我心中已经重新创建(和简体)在ASP.NET MVC 4项目(SignalR 2.2)钉的问题。而且我觉得有一个以上的...
I'm also fairly new to SignalR (and first time user of Angular) so I'v recreated (and simplified) the project in ASP.NET MVC 4 (SignalR 2.2) to nail the problem . And I think there is more then one...
1)SignalR被使用JQuery。在jQuery的(以及几乎任何其他JS框架)的relly更好文件准备事件发生后,以执行code。所以,我在jQuery的文件准备处理程序(见下文code)包裹SignalR设置。
另外我删除 hubConnetion
全局变量,因为全局变量是jQuery的文件准备处理包装后坏+,变量是局部的,处理程序和控制器code反正不能访问。 ..
1) SignalR is using JQuery. In jQuery (and almost any other JS framework) its relly better to execute your code after 'document ready' event. So I wrapped SignalR setup in jQuery document ready handler (see code below).Additionally I removed hubConnetion
global variable because global variables are bad + after wrapping in jQuery document ready handler, variable is local to that handler and not accessible in controller code anyway...
2)主要问题,恕我直言,这是(适用的 SignalR客户端API ):
通常你调用start方法之前注册事件处理程序
建立连接。如果你想注册某些事件
处理程序建立连接后,就可以做到这一点,但你
必须在调用之前注册事件处理程序(S)的至少一个
启动方法。这其中的一个原因是,可以在一个许多集线器
应用程序,但你不想触发OnConnected事件上
每一个集线器,如果你只打算使用其中之一。当。。。的时候
建立连接后,客户端的方法的presence在集线器的
代理是告诉SignalR触发OnConnected事件。 如果您
调用start方法之前没有登记任何事件处理程序,你
将能够调用在集线器的方法,但在集线器的OnConnected
方法将不会被调用,并没有客户端的方法将从调用
服务器
您的事件处理程序是安装在控制器工厂方法被称为很久以后再连接的start()
方法。
尝试添加的临时的调用前处理程序的start()
是这样的:
Your event handler is setup in controller factory method which is called much later then connection start()
method.Try to add temporary handler before calling start()
like this:
$ connection.tasklistHub.client.getTask =功能(){};
3)要确保问题是在SignalR而不是角,我心中已经打开的服务器和客户端的。在所有的上述变化,成功地接收客户端从服务器事件:
3) To be sure the problem is in SignalR and not Angular, i'v turned on both server and client side tracing. After all the changes above, event from server was successfully received on client:
SignalR:轮毂上的客户端触发事件枢纽getTask'TasklistHub
但角失败,接收到的数据进行更新的div。解决办法是使用的。现在一切正常。请参见下面满code。
But Angular failed to update div with data received. Solution is to use $rootScope.$apply
function mentioned in this article about using SignalR and Angular together. Now everything works as expected. See full code below.
旁注:我理解这只是示例code。在任何现实世界中的项目,我会考虑在文章客户包装SignalR枢纽某种服务就像上面提到的或使用的(看起来非常优雅)
Sidenote: I understand this is just sample code. In any real world project I would consider wrapping SignalR hubs on client in some kind of service like in article mentioned above or using this library (looks very elegant)
我也拿回来就客户端的处理程序名称作为根据同一文档我的previous答案,客户端方法的名称匹配是不区分大小写的...
I also take back my previous answer regarding the client side handler name as according to the same document, client side method name matching is case-insensitive...
的 Index.cshtml 的
<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>
的 TodayController.js 的
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;
});
};
}
]
);
这篇关于SignalR客户端不AngularJs控制器内工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!