65.9K
CodeProject 正在变化。 阅读更多。
Home

使用 MVC 和 SammyJS 的单页应用程序

starIconstarIconstarIconstarIconstarIcon

5.00/5 (5投票s)

2015年5月27日

CPOL

5分钟阅读

viewsIcon

23876

downloadIcon

602

如何不使用框架,而是使用 MVC 和 SammyJS 开发单页应用程序(SPA)。

引言

传统的 Web 应用程序大部分驻留在服务器上,浏览器和服务器之间的流量很大,通常涉及 GET、POST(在 WebForms 中,还有令人讨厌的 postback)的请求。越来越多的 Web 应用程序正在采用一种新的模式,即单页应用程序(Single Page Application)或“SPA”。

SPA 的常见示例包括 Facebook 和 Gmail。SPA 的概念是为了给用户提供更好、更响应、更无缝的体验,让他们很少需要离开浏览器,从而避免了冗长乏味的完整页面刷新往返服务器。像 Angular 这样的框架提供了非常强大的方法来创建 SPA,但是当您没有时间学习曲线,或者想要一些轻量级且易于使用的东西时,像 SammyJS 这样非常专注的路由器是一个非常有用的替代方案。本文介绍了使用 SPA 路由器的优势,并解释了如何使用 SammyJS 快速构建一个干净、可扩展、模块化的单页应用程序,并结合 MVC。

为什么使用路由器

让我们考虑一个基于 Web 的通讯录。它将具有非常基本的功能

  • 列出地址
  • 搜索地址功能
  • 创建/编辑/删除地址条目

然而,即使是这些受限的功能,也需要相当的数据录入和管理开销。

 

单页应用程序中工作流的一种常见方法是使用 JavaScript 按钮点击来推动流程。这种方法鼓励行为,例如使用全局变量来跟踪选定/当前数据记录的 ID 或状态。虽然这种方法在一定程度上可行,但它会很快变得混乱。如果我们能解决这个工作流问题,我们就为清晰地分离关注点奠定了基础,从而实现一个更清晰、更可扩展、更易于维护的解决方案。


SammyJS 被描述为“RESTful、事件驱动的 JavaScript”。它允许我们在客户端以 MVC 的方式进行工作。正如我们在 MVC 和 Web-API 中拥有可以接受 get/post/delete 等动词的控制器一样,我们也可以使用 SammyJS 来实现这些模式。
在传统的 Web 服务器中,我们通过完整的路由来访问控制器,而 SammyJS 的路由则使用锚点标签“#”来连接路由——您可以在下面的示例中看到这一点,该示例使用标准的“GET”动词从“#home”路由请求数据。

   this.get('#home', function (){ 
      // do something here and send data back to the caller
   })

使用代码 - 设置

为了让 SammyJS 正常运行,我们需要初始化它,并添加一些路由。 

    //initialize "SAMMY"
    var app = $.sammy(function () {

        this.get('#home', function () {
            // show home screen
        });

        this.get('#address/create', function () {
            // show create new address screen
        });

    }).run('#home');//run it with default html fragment


在上面的代码中,我们使用“run”方法初始化库并同时激活它,将默认路由设置为“#home”。我们现在有两个路由,一个向用户提供主页,另一个显示创建新地址的屏幕。两者都使用简单的 GET 动词。本文的目的是让您快速上手 SammyJS,将其用作 MVC 应用程序中的路由解决方案,因此我现在将介绍常见的用例场景以及它们可能如何工作——我们将避免构建一个完整的应用程序,即使是微不足道的。

使用代码 - 路由和动词

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







This is the Home div

<!-- master div that will be used to host other divs -->

 

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

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

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

<form id="simpleForm" action="#/post/form" method="POST">
    <label>Some Name</label>
<input type="text" name="some_name" value="a simple name" /> <input type="submit" value="Submit" /> </form>
前两个示例路由非常基本,它们根据路由指令显示/隐藏不同的 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)
        });
与表单一起工作的方式类似。声明表单(注意方法和操作路由)。
<form id="simpleForm" action="#/post/form" method="POST">
    <label>Some Name</label>
<input type="text" name="some_name" value="a simple name" /> <input type="submit" value="Submit" /> </form>
使用 SammyJS,我们然后提取表单中发送的值。(这里有一个小问题,您需要通过返回“false”来阻止表单默认的 post back 到服务器)。
        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
        });

超越路由器

创建单页应用程序有许多挑战,包括内存管理、与服务器的数据交换等。这里有一个小的示例,它获取一个新更新的服务器端部分页面,并用它来更新用户界面。
<!-- master div that will be used to host other divs -->
// Sammy routing
 this.get('#GetRemote', function () {
            hideAll();
            GetRemoteDiv();
        });

// Ajax call to get remote html to replace page content
    var GetRemoteDiv = function () {
        $.ajax({
            method: 'get',
            url: '/home/LoadDivFromRemote'
            }
           ).done(function (dataRcvd) {
               $('#divContent').empty();
               $('#divContent').show();
               $('#divContent').html(dataRcvd);
           });
    }
// server-side C# code that generates the dynamic page data

 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");
        }

@ViewBag.Title

@ViewBag.Message

总结

本文重点介绍了路由的核心概念——您如何使用路由是另一回事——我建议您浏览 SammyJS 网站上的“JSON Store”示例(第一部分第二部分),以深入了解此库的功能。

SammyJS 附带了大量非常有用的插件,涵盖了 html 模板、客户端本地存储、SPA 谷歌分析助手等主题。

我强烈建议您下载示例代码并试用 SammyJS。

其他资源

要更深入地了解使用微软技术构建 SPA 的架构,请阅读Mike Wasson 在 msdn 上的文章。以下是关于单页应用程序的另外两个相当深入的通用资源。

最后,如果本文对您有帮助,请不要忘记在页面顶部给它投票!

历史

2015 年 5 月 27 日 - 版本 1

© . All rights reserved.