信号机的RequireJS模块

信号机的RequireJS模块,requirejs,signalr,Requirejs,Signalr,我没有把我的代码复制粘贴到这里,而是把它上传到了。RequireJS模块确实依赖于jquery.signar,tern依赖于jquery,但也依赖于/signar/hubs中的javascript。在Require.config中有一些配置 基本上,当您第一次加载页面时,会连接到signalr中的集线器,执行“服务器端”代码并执行所需的操作。当你刷新页面时,它不会。调用所有客户端代码,例如: var myViewModel = new MyViewMode(); myViewModel.init

我没有把我的代码复制粘贴到这里,而是把它上传到了。RequireJS模块确实依赖于jquery.signar,tern依赖于jquery,但也依赖于/signar/hubs中的javascript。在
Require.config
中有一些配置

基本上,当您第一次加载页面时,会连接到signalr中的集线器,执行“服务器端”代码并执行所需的操作。当你刷新页面时,它不会。调用所有客户端代码,例如:

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();
的状态吗

喝啤酒的时间:)

我想应该是

connection.client.populateSomeInformation = function () { .. )
(不是连接服务器)


(对您目前在github上的代码的观察)

var isLoaded=false;
// ... 一些不会更改的代码已加载。。。
如果(isLoaded==false){
scrollIntervalId=window.setInterval(函数(){
signalLoaded();
}, 30);
}
我认为,
isLoaded
在这一点上总是错误的。我不确定你打算做什么

var connection=$.connection.hub.start();
我认为在定义任何客户端函数之前都不应该打开连接。我看不到这里定义了任何客户机函数,所以您可能在其他地方这样做?我不知道这是否真的很重要,除了服务器是否尝试调用尚未定义的客户机函数

函数信号READY(回调){
如果(已加载){
回调(连接);
}否则{
readyCalls=回调;
}
返回信号日;
}
SignalRReady.version=“1.0.0”;
SignalRReady.load=函数(名称、请求、onLoad、配置){
if(config.isBuild){
onLoad();
}否则{
信号准备(空载);
}
};
返回信号日;
我被这段代码弄糊涂了,可能是因为我不知道它是如何被使用的。这是一种单身的尝试吗?我看到SignalReady是为模块返回的“类”。您并不是真正返回一个对象,而是返回一个构造函数,这意味着您正在其他地方实例化它,比如

define(['SignalRReady'],函数(sigR)
{
var srr=新的sigR();
});
但随后定义了调用构造函数的
load
函数,这让它看起来很奇怪。你怎么用这个

无论如何,我认为您可能遇到了某种竞争条件,在服务器试图调用客户端函数时,客户端函数可能并不总是可用的


(附加注释/代码2013-09-06)

您的连接对象实际上是一个jQuery承诺()

如果您不熟悉承诺,请将它们一般地视为稍后执行的回调队列。在这种情况下,当连接时,将执行所有回调(按添加顺序)。如果在连接后添加回调,它将立即执行。这就是您的代码现在的工作方式。在建立连接并立即执行后,将回调添加到.done队列

如果坚持自己创建连接对象,则不需要使用stateChanged事件。您只需将回调添加到.done队列:

define(函数()
{
函数信号READY(回调)
{
if(window.connection==未定义){
window.connection=$.connection.hub.start();
}
window.connection.done(回调);
}
signalRReady.version=“1.0.0”;
返回信号日;
});
然而,我认为自己建立联系不是一个好主意。由于您的模块不是信号器的完整包装器,因此人们只能使用您的模块来完成信号器的工作,因此您不能保证(也不能期望)其他代码不会启动连接。尤其是当有人将您的模块添加到现有代码库时

您的模块只是添加了一个新事件,所以请保持简单。在适当的时候,自己执行回调:

define(函数()
{
函数信号READY(回调)
{
$.connection.hub.stateChanged(函数(状态)
{
if(state.newState==$.signalR.connectionState.connected)
{
回调();
}
});
}
signalRReady.version=“1.0.0”;
返回信号日;
});
如今,承诺很受欢迎。您可能希望实现基于承诺的模块,如:

define(函数()
{
var deferred=$.deferred();
$.connection.hub.stateChanged(函数(状态)
{
if(state.newState==$.signalR.connectionState.connected)
{
//执行下面“ready”函数附加的所有回调
延迟。解决();
}
});
返回{
就绪:函数(回调)
{
延迟。完成(回调);
},
版本:“1.0.0”
};
});
如果在建立连接后附加回调,则会立即执行回调

另外,请注意,这个示例模块的init函数返回一个对象而不是函数。因为RequireJS会将同一个实例传递给任何需要它的模块,所以状态是保持的——我们可以使用局部变量而不是全局变量。

我认为应该是这样

connection.client.populateSomeInformation = function () { .. )
(不是