SignalR $.connection是未定义的。

33

我承认,我不知道自己在做什么。

我正在尝试学习如何使用SignalR,我几乎逐字逐句地按照在线示例进行,但无法通过$.connection被定义的问题。我正在使用MVC 4.0,并尝试使用NuGet下载的SignalR js文件或来自示例项目的文件。这是我的脚本引用。

@Scripts.Render("~/Scripts/jquery-1.7.2.min.js")
@Scripts.Render("~/Scripts/knockout-2.0.0.js")
@Scripts.Render("~/Scripts/jquery.signalR.js")
@Scripts.Render("~/signalr/hubs")

脚本似乎加载了,我甚至在它们开头放置了警报,但是 $.connection 总是未定义。

奇怪的是,我有另一个项目,我试图使用不同的 jQuery 库,它使用 $。那个对象也总是未定义。

我只是在寻找可能解释我可能做错了什么的任何可能性。非常感谢提前。


我们连一行代码都没有,怎么能提供帮助呢? - Cranio
5
页面上是否有两个相同版本的jQuery库? - davidfowl
@davidfowl的评论解决了我的问题。我在视图中包含了jQuery脚本,并且在共享文件夹中的布局视图中也包含了它。 - Patrick Thorpe
5个回答

69

今天我遇到了同样的问题。

你的答案指导了我正确的方向,因为我的脚本加载设置与你完全相同。

我将所有的脚本标签放在页面顶部(head)按照以下顺序。

  • JQuery
  • SignalR
  • /signalr/hubs
  • my-script.js

当然,@Layout.cshtml考虑周全,在标签底部添加了@Scripts.Render("~/bundles/jquery")

发生了什么?

在这种配置中,当页面加载时,它按照指定的顺序加载head标签中的所有脚本。

因此它先加载JQuery,然后是SignalR,它设置了$.connection,接着是自动生成的hubs脚本,它设置了$.connection.hubName,最后是站点的自定义脚本。

此时开始运行您的自定义代码。但是您的代码在某个时间点等待body.onloaddocument.onReady再访问$.connection

此事件触发时,模板添加到body标记末尾的脚本绑定也会下载和执行。此绑定包含了jquery库...它会重置SignalR在$上设置的所有内容,现在您的$.connection不再被定义。

如何解决

修复很简单,确保不要重复加载JQuery,一次在SignalR之前,一次在SignalR之后。我将所有脚本都移到了bundle之后,并解决了这个问题。最佳实践是使用模板提供的“scripts”部分。

@section scripts{
    @*/* load your scripts here. You can exclude jQuery, 
      coz it's already in the template */ *@
}

所以这根本不是 SignalR 的错误...

那就是我浪费掉的两个小时...永远都拿不回来了...

希望这可以帮到你。


1
太棒了,谢谢。虽然还是不行,但是已经更接近了(控制台没有错误信息了)! - user1477388
1
你太棒了!它起作用了,拯救了那些遇到同样问题的其他开发者“两个小时的时间”:) - Kings
我正在跟随一个Pluralsight课程,该课程还向每个视图添加了jQuery脚本,忘记了该布局已经有它们了。{{doubleFACEPALM}} - Mike Devenney
1
只有2小时?不错。 - eaglei22
如果您正在使用asp.net mvc,您还可以使用bundles来捆绑您的SignalR脚本,并在布局文件(或任何其他调用bundles的位置)中最后加载该bundle。 - eaglei22
我花了一整天的时间试图找出第二个引用是从哪里来的,最终才发现它是由DevExpress自动包含的(隐藏在DXR.axd脚本中)- 参见此链接。希望这个知识能够为某人节省些时间。 - AvahW

11

我解决了这个问题。我知道我做了什么,但我不确定为什么它确实有效。

我在_Layout.cshtml视图的顶部引用了主要的jquery库(版本1.7.2),但没有引用其他任何jquery脚本。我注意到默认情况下,在布局视图中它正在加载

@Scripts.Render("~/bundles/jquery") 

在视图底部,并且下面有一个位置为脚本的部分。

@RenderSection("scripts", required:false)
我进一步更改了我的脚本引用,如下所示,并把我在问题中展示的脚本引用放在了一个

标签中。
@section scripts
{    
   @Scripts.Render("~/Scripts/jquery.signalR-0.5.1.js")
   @Scripts.Render("~/Scripts/jquery.color.js")
   @Scripts.Render("~/signalr/hubs")
   @Scripts.Render("~/Scripts/blasht.signalr.js")
}

在我的视图中包装器,以便它们在捆绑加载后被包含。我认为之前没有加载所有必要的jQuery,因为现在它可以正常工作。

现在,如果我能弄清楚这如何适用于我的其他项目。


3
这个技巧的原理在于javascript文件被加载的顺序。如果你尝试在加载jquery之前加载jquery.signalR-0.5.1.js,那么你将遇到$.connection未定义的问题,因为要注册这个,必须先加载jquery。在_Layout.cshtml模板中, script按照一定顺序加载。
@Scripts.Render("~/bundles/jquery")

@RenderSection("scripts", required: false)

所以在任何一个视图中,您都可以在脚本部分加载signalr,这应该可以正常工作。


2

我曾经遇到过同样的问题。 在我的页面和布局中,我都引入了两次 jQuery。 移除其中一个后,问题得到解决。

希望对你有所帮助。


0

这是因为我在加载jquery.signalR-1.1.4.js脚本之前动态加载了~/signalr/hubs脚本。

当动态加载时,没有出现错误,但是如果我将~/signalr/hubs的输出粘贴到我的Chrome开发工具中,我会收到一个错误消息VM1047:18 Uncaught Error: SignalR: SignalR未加载。请确保在~/signalr/hubs之前引用jquery.signalR-x.js。 at <anonymous>:18:15 at <anonymous>:300:2


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接