探索单页应用(SPA)与SammyJS路由

在传统的Web应用中,服务器端占据了主导地位,浏览器和服务器之间的流量非常密集,使用GET、POST请求(在Web表单中,还有可怕的回传)是常态。然而,越来越多的Web应用开始采用一种新的范式——单页应用(SPA)。Facebook和Gmail就是SPA的典型例子。SPA的核心概念是为用户提供更好、更响应、更无缝的体验,这样用户就很少需要离开浏览器,从而避免了长时间的全页面刷新往返服务器。Angular等框架提供了非常强大的方法来创建SPA,但如果没时间学习曲线,或者想要一些轻量级且简单的解决方案,像SammyJS这样的专注于路由的库是一个非常有用的选择。本文将介绍使用SPA路由的好处,并解释如何使用SammyJS快速构建一个清晰、可扩展、模块化的单页应用。

为什么使用路由

让考虑一个基于Web的地址簿。它将具有非常基础的功能:列出地址、搜索地址功能、创建/编辑/删除地址条目。即使这些功能受限,但它们仍然需要合理的数据输入和管理开销。在单页应用中,常见的工作流程方法是使用JavaScript按钮点击来推动事情的发展。这种方法鼓励使用全局变量来跟踪选定的当前数据记录的ID或状态。虽然这种方法在一定程度上是可行的,但它很快就会变得混乱。如果能够解决这个工作流程问题,就有清晰的关注点分离的基础,这将允许一个更清晰、可扩展和更易于维护的解决方案。

SammyJS简介

SammyJS被描述为“RESTful,事件驱动的JavaScript”。它允许以MVC的方式工作,但这是在客户端。就像在MVC和Web-API中有控制器可以接受GET/POST/DELETE等动词一样,也可以在SammyJS中实现这些模式。在传统的Web服务器中,使用完整的路由来访问控制器,而SammyJS路由则使用锚标签“#”来连接路由——可以在下面的例子中看到,它使用标准的“GET”动词从“#home”路由请求数据。

设置代码

要让SammyJS运行起来,需要初始化它,并添加一些路由。

var app = $.sammy(function() { this.get('#home', function() { // 显示首页屏幕 }); this.get('#address/create', function() { // 显示创建新地址屏幕 }); }).run('#home');

在上面的代码中,初始化了库,并使用“run”方法同时激活它,给出了默认路由“#home”。现在有两个路由,一个为用户提供首页,另一个显示创建新地址屏幕。两者都使用简单的GET动词。本文的目标是让快速上手SammyJS作为路由解决方案,用于MVC应用,所以将现在运行常见的用例场景以及它们是如何工作的——将避免构建一个完整的应用程序,无论多么琐碎。

使用代码 -路由和动词

为了演示目的,创建了一些DIV,它们将作为显示表单/区域,根据用户选择的路由显示/隐藏。这些可以被分离到单独的cshtml文件中,并使用HTML.Partial(..)进行渲染。

This is the Home div

当然,路由必须从某个地方调用——有一个基本的菜单结构,展示了不同的用例。

Home | Show Div 1 | Show Div with param | Re-direct to div 1 | Get div content from server

还有一个简单的HTML表单,将用于演示发布表单数据。


前两个示例路由非常基础,它们根据路由指令向用户显示/隐藏不同的DIV。

this.get('#home', function() { hideAll(); $('#divHome').fadeIn(); }); this.get('#d1', function() { hideAll(); $('#div1').fadeIn(); $('#div1_SomeLabel').text(''); });

有时希望将用户从一个路由发送到另一个路由——这就是重定向方法的用武之地。

this.get('#d4', function() { hideAll(); this.redirect('#d1'); $('#div1_SomeLabel').text('Redirect from some a-tag'); });

下一个示例展示了如何从发送的查询字符串中获取值——首先,这里是调用路由的HTML。

Show Div with param

注意参数“id”和值“1234”。使用“params”在路由中访问查询名称和值。注意路由模式中的占位符“:”和被访问的“params”值。

this.get('#d2/:id', function() { hideAll(); var tempID = this.params['id']; $('#div2').fadeIn(); $('#div2_ParamVal').text(tempID) });

处理表单的操作方式类似。声明表单(注意方法和动作路由)。

this.post('#/post/form', function() { alert('here with ' + this.params['some_name'] + '\n\nNow hiding the form!'); $('#simpleForm').hide(); return false; // stops the default POST behaviour back to server });

路由之外

创建一个单页应用有很多挑战,包括内存管理、与服务器的数据交换等。这里有一个小型示例,展示了如何获取一个全新的、更新的服务器端部分页面,并使用它来更新用户的界面。

Sammy路由。

this.get('#GetRemote', function() { hideAll(); GetRemoteDiv(); });

Ajax调用获取远程HTML以替换页面内容。

var GetRemoteDiv = function() { $.ajax({ method: 'get', url: '/home/LoadDivFromRemote' }).done(function(dataRcvd) { $('#divContent').empty(); $('#divContent').show(); $('#divContent').html(dataRcvd); }); }

服务器端C#代码生成动态页面数据。

public ActionResult LoadDivFromRemote() { ViewBag.Title = "Remotly injected!"; ViewBag.Message = "This div was remotly injected into the dom from the server at: " + DateTime.Now.ToLongTimeString(); return PartialView("~/Views/Home/RemoteDiv.cshtml"); }

HTML。

@ViewBag.Title

@ViewBag.Message

本文专注于路由的核心概念——如何使用路由是另一回事——建议通过SammyJS网站上的“JSON Store”示例(第一部分,第二部分)来深入理解这个库的能力。SammyJS附带了一系列非常有用的插件,涵盖了HTML模板、客户端本地存储、SPA谷歌分析助手等主题。强烈建议下载示例代码并尝试SammyJS。

沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485