如何建立Facebook风格的Ajax网站

时间:2010-09-19 23:00:57

标签: javascript asp.net asp.net-mvc ajax

我知道标题有点模糊且无所不包,所以请让我尝试缩小范围。

我想要的是关于如何开发一个主要是Ajax网站的建议,其中部分UI是异步加载的。这就是问题所在:我希望浏览器的后退/前进按钮能够直观地运行 - 这是Facebook取得的非常好的成就。

有谁知道Facebook使用的库和设计模式?考虑到他们做得非常出色,将它们用作模型是很有意义的,而不是试图重新发明轮子。

我注意到url hash中有很多内容:
http://www.facebook.com/home.php?#!/home.php?sk=bd

我确信他们必须有充分的理由这样做,如果这是我可以利用的东西,我不会感到惊讶。有人可以指出他们在这里完成了什么,以及?#!/home.php?sk=bd的每个部分用于什么?我特别惊讶地看到home.php?sk=bd,当加载的原始页面是home.php时 - 可能是他们允许链接到特定“页面”的方式,尽管整个事情都由{ {1}}?

要解决每个问题并不是那么重要 - 我真的只是想要传达我理解困难的东西 - 如果你愿意,那就是“更大的图景”。如果有人可以给我一个更全面的答案,那就太棒了(特别是如果你能告诉我如何使用ASP.NET MVC实现这一点)。

提前致谢!

2 个答案:

答案 0 :(得分:2)

我们已经构建了一个像你描述的应用程序,这是我们最终做的:

  1. 服务器只通过JSON数据与浏览器进行讨论。
    XML消息传递也可以,但在所有浏览器中都难以处理。
  2. 前端仅由静态文件构建:HTML,CSS,JS。服务器只处理数据库的安全性和事务。
    所有HTML都在客户端呈现,pure.js是一个Javascript模板引擎,它可以干净地分离HTML视图和JS逻辑。
  3. 对于导航,我们使用哈希键(#)作为应用程序的状态。例如:用户正在看什么人。在测试了许多解决方案后,我们最终构建了一个非常简单的解决方案,使用120毫秒的setInterval轮询,检查散列键的值是否有任何变化。
  4. 该应用程序非常灵敏,导航非常直观。

    修改
    由于我们放弃了对IE6和IE7的支持,我们不再轮询散列更改,而是使用window.onhashchange

答案 1 :(得分:1)

我使用的技术与Mic相似。我的工具包的基本部分:

  • 一个javascript构建系统。我使用ant将我所有的小js源文件滚动到一个大的最终文件中。通过这种方式,我可以保持文件尽可能小,而不必担心必须将100个单独的脚本导入浏览器。

  • 模板引擎。我正在使用Trimpath并对此非常满意。除了Trimpath之外,我还开发了自己的系统来处理包含和模板继承,我用它来处理我的模板代码,然后再交给Trimpath。

  • 模板文件的预处理器,可将多行字符串转换为有效的javascript。通过这种方式,我可以编写常规的多行html,将其交给我的脚本,将其转换为javascript,然后将模板转换为主js文件,而不必单独提供。

  • 处理异步调用的技巧。在很多情况下,为了渲染屏幕,我需要确保加载dataA,dataB和dataC。我没有创建服务器端调用“fetchDataABandC”,而是有一个客户端函数,我可以使用它来指定“执行A,B和C,并在完成所有操作后调用此回调”。我还可以指定“按A然后B然后C,顺序”。我发现自己做了很多事情的另一件事是设置函数,以便它们可以很容易地转入异步调用。所以,通常,每当我有一个获取数据的函数,而不是让该函数返回一个值时,我都会传递一个回调函数。例如,如果我将一些数据存储在cookie中,稍后我决定将该数据移动到服务器,如果我用来获取和设置该数据的函数是基于回调的,则很容易换出通过服务器调用实现。

  • 缓存机制。我的所有服务器调用都是通过一个“服务”对象访问的。我有一个缓存对象,它包装Service对象,复制对象的每个方法,并添加一个名为{methodName}缓存的附加方法。因此,如果原始服务对象具有一个名为“getSubscriberDetails”的方法,则缓存对象将为其自身动态创建“getSubscriberDetails”方法,该方法链接回原始方法,还有“getSubscriberDetailsCached”方法,如果它返回缓存数据存在,但否则将调用原始函数(并缓存它返回的数据)。在内部,缓存使用方法名称和方法参数生成的密钥存储数据,因此如果我调用cache.getSubscriberDetailsCached(“subscriber1”),则不同于cache.getSubscriberDetailsCached(“subscriber2”)。

  • 小部件之间进行通信的事件系统。我正在构建的软件是一个联系人管理系统。如果我有一个列出所有用户联系人的小部件,以及允许用户添加和删除联系人的另一个小部件,则需要通知联系人列表小部件发生了哪些更改。我没有让“添加联系人”小部件保持对依赖于联系人列表的每一个其他功能的认识,而是使用jquery的事件系统向具有“contactsChangedListener”类的dom对象发送“contactsChanged”事件。 。所以,我的“联系人列表”小部件在其最外层的div中有“contactssChangedListener”类,我通过jQuery.bind在“联系人列表”控制器中附加一个监听器。当“contactsChanged”事件被发送出去时,我的“联系人列表”小部件知道它需要刷新其联系人列表。

  • 基于哈希的导航。我正在使用jquery hashchange插件来帮助我监听哈希更改。每个屏幕都与一个单独的网址相关联,您从一个屏幕移动到另一个屏幕的方式是更改网址。我不使用直接链接。每个导航操作都会通过一个导航器对象,该对象可以配置为执行一些操作,例如弹出一条警告消息,告诉用户他们将要丢失未保存的更改。