2010-09-19 34 views
4

据我所知,标题有点含糊,无所不包,所以请让我试着缩小范围。如何构建Facebook风格的Ajax网站

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

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

我注意到,有很多在URL哈希回事:
http://www.facebook.com/home.php?#!/home.php?sk=bd

我敢肯定,必须有他们这样做的一个很好的理由,我也不会感到惊讶如果这是我可以利用的东西。有人可以指出他们在这里完成了什么,以及那个?#!/home.php?sk=bd的每个部分用于什么?当我看到home.php?sk=bd,当加载的原始页面是home.php--这可能是他们允许链接到特定“页面”的方式,尽管整个事件由home.php服务吗?我特别惊讶。

解决每个问题并不是那么重要 - 我只是在试图表达我无法理解的东西 - 如果您愿意的话,我会说“更大的图片”。如果有人能给我一个更全面的答案,那就太棒了(特别是如果你能告诉我如何使用ASP.NET MVC来完成)。

在此先感谢!

+0

不是一个答案,但我相信重复哈希路径是一个解决方案,用户没有脚本看到一些相关的页面,如果不是正确的单击链接/书签后。 – 2010-09-19 23:13:06

+1

哦,顺便说一句,#!是谷歌使用的一个避难所。由于您将制作一个AJAX网站,因此注意这一点非常重要。更多信息在这里:http://searchengineland.com/googles-proposal-for-crawling-ajax-may-be-live-34411注意,当然它*已经工作*。 – 2010-09-19 23:15:46

+0

“#!”的用途这样就可以在没有浏览器强制页面重新加载的情况下使用Javascript修改URL。这样,您可以修改浏览器URL以匹配您的AJAX调用,而无需重新加载页面。 – Jemes 2010-09-20 01:03:20

回答

2

我们已经建立了一个应用程序像你描述,这里就是我们所做的最后:

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

该应用程序非常灵敏,导航非常直观。

编辑:
由于我们丢弃我们不再轮询哈希值发生变化,而是用我使用的技术的类似麦克风的window.onhashchange

1

的IE6和IE7的支持。我的工具包的基本部分:

  • 一个javascript构建系统。我用蚂蚁把我所有的小js源文件放到一个大的最终文件中。这样我就可以保持我的文件尽可能小,而不用担心必须将100个单独的脚本导入到浏览器中。

  • 模板引擎。我使用的是Trimpath,并且一直很满意。除了Trimpath之外,我还开发了自己的系统来处理包含和模板继承,我用这些系统来处理我的模板代码,然后交给Trimpath。

  • 模板文件预处理器将多行字符串转换为有效的javascript。这样,我可以编写常规的多行html,将其交给我的脚本,该脚本将其转换为javascript,然后可以将我的模板滚动到主js文件中,而不必单独提供它们。

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

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

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

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

+0

有意思......它看起来我们是在相同的小部件种类的任务;)虽然,我没有选择DOM,但JS对象注册事件。我在测试时并不相信trimpath,并为此构建了pure.js。 – Mic 2010-09-20 14:58:37

+0

小工具任务!我喜欢使用dom进行事件的注册和注销监听器是非常自动的。如果您删除了一个小部件,您不必担心清理对该小部件的引用,它只会自动发生。 Pure.js是你的吗?凉! – morgancodes 2010-09-20 15:20:11