我没有将代码复制并粘贴到此处,而是将其上传到github。 RequireJS模块确实依赖于jquery.signalr,并且tern依赖于jquery,但也依赖于/ signalr / hubs中保存的javascript。有一些与Require.Config
配置的配置。
基本上发生的事情是在您第一次加载页面时,连接到信号器内的集线器并执行“服务器端”代码并执行所需的操作。当您刷新页面时,它不会。调用所有客户端代码,例如:
var myViewModel = new MyViewMode();
myViewModel.init();
并在您的init方法中
var connection = $.connection.myHub;
this.init = function() {
connection.server.myMethod();
}
然后会转到
public MyHub : Hub
{
public void MyMethod()
{
Client.Request.populateSomeInformation() // I think it's request but I'm doing this from memory!
}
}
然后致电
connection.client.populateSomeInformation = function () { .. )
但不称之为:(
看起来就像已建立连接一样(使用旧的console.log()
来查看它输出的内容)并确实调试项目它在集线器中执行代码但是没有响应回到了javascript。
互联网上这么好的人,我哪里错了?在尝试再次启动之前,是否需要检查$.connection.hub.start();
的状态?
啤酒的时间:)
答案 0 :(得分:1)
我认为应该是
connection.client.populateSomeInformation = function () { .. )
(不是connection.server)
http://www.asp.net/signalr/overview/hubs-api/hubs-api-guide-javascript-client#callclient
(关于你现在在github上的代码的观察)
var isLoaded = false;
// ... some code that doesn't change isLoaded ...
if (isLoaded == false) {
scrollIntervalId = window.setInterval(function () {
signalRLoaded();
}, 30);
}
我认为isLoaded
此时总是假的。不确定你打算做什么。
var connection = $.connection.hub.start();
在定义任何客户端函数之前,我认为你不应该打开连接。我没有看到这里定义了任何客户端功能,所以也许你在其他地方这样做了?除了服务器试图调用尚未定义的客户端函数之外,我不知道它是否真的重要...
function SignalRReady(callback) {
if (isLoaded) {
callback(connection);
} else {
readyCalls = callback;
}
return SignalRReady;
}
SignalRReady.version = "1.0.0";
SignalRReady.load = function(name, request, onLoad, config) {
if (config.isBuild) {
onLoad();
} else {
SignalRReady(onLoad);
}
};
return SignalRReady;
我对这段代码感到困惑,可能是因为我看不到它是如何被使用的。这是一种单身人士的尝试吗?我看到SignalRReady是为模块返回的“类”。你并没有真正返回一个对象,你正在返回一个构造函数,暗示你在其他地方实例化它,比如
define(['SignalRReady'], function(sigR)
{
var srr = new sigR();
});
但是你已经定义了load
函数来调用构造函数并使它看起来很奇怪。你是怎么用的?
无论如何,我想你可能会遇到某种竞争条件,在服务器试图调用它时,客户端功能可能并不总是可用。
(附加评论/代码2013-09-06)
您的连接对象实际上是一个jQuery承诺(http://api.jquery.com/category/deferred-object/)。
如果您不熟悉承诺,请将它们一般地视为稍后要执行的回调队列。在这种情况下,连接时,将执行所有回调(按照添加的顺序)。如果在连接后添加回调,它将立即执行。这就是您的代码现在的工作方式。在建立连接后将回调添加到.done队列并立即执行。
如果您坚持自己创建连接对象,则不需要使用stateChanged事件。您只需将回调添加到.done队列:
define(function()
{
function signalRReady(callback)
{
if (window.connection == undefined) {
window.connection = $.connection.hub.start();
}
window.connection.done(callback);
}
signalRReady.version = "1.0.0";
return signalRReady;
});
但是,我认为自己启动连接并不是一个好主意。因为你的模块不是SignalR的完整包装器,所以人们只会使用你的模块做SignalR的东西,你不能保证(并且不能指望)其他代码不会启动连接。特别是如果有人将您的模块添加到现有代码库中。
您的模块只是添加一个新事件,因此请保持简单。接受回调并在适当时自行执行:
define(function()
{
function signalRReady(callback)
{
$.connection.hub.stateChanged(function (state)
{
if(state.newState === $.signalR.connectionState.connected)
{
callback();
}
});
}
signalRReady.version = "1.0.0";
return signalRReady;
});
如今,承诺很受欢迎。您可能希望实现基于承诺的模块,如:
define(function()
{
var deferred = $.Deferred();
$.connection.hub.stateChanged(function (state)
{
if(state.newState === $.signalR.connectionState.connected)
{
// executes all callbacks attached by the "ready" function below
deferred.resolve();
}
});
return {
ready: function(callback)
{
deferred.done(callback);
},
version: "1.0.0"
};
});
如果在建立连接后附加了回调,则立即执行回调。
另外,请注意此示例模块的init函数返回一个对象而不是一个函数。由于RequireJS会将相同的实例传递给任何需要它的模块,因此维护状态 - 我们可以使用局部变量而不是全局变量。