BackBone结合ASP.NET MVC实现页面路由操作

1 问题的背景

什么是页面路由操作,就是通过浏览器地址栏的标记来实现页面内部的一些操作,这些操作具有异步性和持久性。应用场景主要有页面操作过程中的添加收藏夹的操作、后退操作等过程中能完全恢复界面。

Html中window.history.pushState的出现实现了页面路由操作。由于操作比较复杂,我们采用backbone的封装的路由操作来实现下面的案例。

2 实现目标

我们要实现的应用程序左侧导航,右侧展示数据。可以加入收藏夹,可以回退,恢复和回退时可以完全恢复现场。

这个程序的逻辑思路为按照班级筛选学生

程序截图如下

 

当程序加载时我们观察浏览器栏的变化

http://localhost:56968/#searchByClassCode/all

 

当我们点击导航【三年一班】时,我们观察浏览器栏的变化

http://localhost:56968/#searchByClassCode/0301

我们发现浏览器栏里的数据变为0301

如图所示

 

 

当我们点击【三年二班】,我们观察浏览器栏的变化

http://localhost:56968/#searchByClassCode/0302

我们发现浏览器栏里的数据变为0302

如图所示

 

当我们点击后退时,我们观察浏览器栏的变化

http://localhost:56968/#searchByClassCode/0301

我们发现浏览器栏里的数据变为0301

我们总结出下面的结论

1、将http://localhost:56968/#searchByClassCode/0301加入收藏夹,当点击收藏夹时,能完整的还原现场。

2、点击后退时能退回到【三年一班】

3、整个过程都是异步刷新,没有同步刷新。

 3、 实现的工具和材料

VS2010+MVC4+Backbone.js。必须要装MVC4

4、 实现整体过程

1、新建mvc项目

在model文件夹 新建Student的类,定义如下

  public class Student
    {
        #region 学号
        /// <summary>
        /// 学号
        /// </summary>
        public string Number
        {
            get;
            set;
        }
        #endregion

        #region 姓名
        /// <summary>
        /// 姓名
        /// </summary>
        public String Name
        {
            get;
            set;
        }
        #endregion

        #region 班级
        /// <summary>
        /// 班级
        /// </summary>
        public String ClassName
        {
            get;
            set;
        }
        #endregion

        #region 班级编码
        /// <summary>
        /// 班级编码
        /// </summary>
        public string ClassCode
        {
            get;
            set;
        }
        #endregion

2 新建HomeController

里面的两个路由地址分别为Index和GetList。其中Index用于显示页面

GetList用于提供数据服务,其中classCode为班级代码,用于查询某个班级下的学生,如果参数值为空或all就取所有的,否则就按照编码检索,返回值数据为json数据

实现如下

 public class HomeController : Controller
    {
        /// <summary>
        /// 主页
        /// </summary>
        /// <returns></returns>
        public ActionResult Index()
        {
            return View();
        }
        /// <summary>
        /// 获取数据
        /// </summary>
        /// <param name="classCode"></param>
        /// <returns></returns>
        public ActionResult GetList(string classCode)
        {
            string content = new StreamReader(Server.MapPath("~/Content/Data/Student.json")).ReadToEnd();
            List<Student> list = Newtonsoft.Json.JsonConvert.DeserializeObject<List<Student>>(content);
            if (!string.IsNullOrEmpty(classCode))
            {
                if (classCode != "all")
                {
                    list = list.Where(item => item.ClassCode == classCode).ToList();
                }
            }
            return new JsonResult()
            {
                Data = list,
                JsonRequestBehavior = JsonRequestBehavior.AllowGet
            };
        }
    }

 为了方便数据的提供服务采用json文件的方式,并没有采用关系型数据库,数据如下:

[{
    "Number": "000001",
    "Name": "学生1",
    "ClassName": "三年一班",
    "ClassCode": "0301"
},
{
    "Number": "000002",
    "Name": "学生2",
    "ClassName": "三年二班",
    "ClassCode": "0302"
},
{
    "Number": "000003",
    "Name": "学生3",
    "ClassName": "三年三班",
    "ClassCode": "0303"
},
{
    "Number": "000004",
    "Name": "学生4",
    "ClassName": "三年四班",
    "ClassCode": "0304"
},
{
    "Number": "000005",
    "Name": "学生5",
    "ClassName": "三年一班",
    "ClassCode": "0301"
},
{
    "Number": "000006",
    "Name": "学生6",
    "ClassName": "三年二班",
    "ClassCode": "0302"
},
{
    "Number": "000007",
    "Name": "学生7",
    "ClassName": "三年三班",
    "ClassCode": "0303"
},
{
    "Number": "000008",
    "Name": "学生8",
    "ClassName": "三年四班",
    "ClassCode": "0304"
},
{
    "Number": "000009",
    "Name": "学生9",
    "ClassName": "三年一班",
    "ClassCode": "0301"
},
{
    "Number": "000010",
    "Name": "学生10",
    "ClassName": "三年二班",
    "ClassCode": "0302"
},
{
    "Number": "000011",
    "Name": "学生11",
    "ClassName": "三年三班",
    "ClassCode": "0303"
},
{
    "Number": "000012",
    "Name": "学生12",
    "ClassName": "三年四班",
    "ClassCode": "0304"
},
{
    "Number": "000013",
    "Name": "学生13",
    "ClassName": "三年一班",
    "ClassCode": "0301"
},
{
    "Number": "000014",
    "Name": "学生14",
    "ClassName": "三年二班",
    "ClassCode": "0302"
},
{
    "Number": "000015",
    "Name": "学生15",
    "ClassName": "三年三班",
    "ClassCode": "0303"
},
{
    "Number": "000016",
    "Name": "学生16",
    "ClassName": "三年四班",
    "ClassCode": "0304"
},
{
    "Number": "000017",
    "Name": "学生17",
    "ClassName": "三年一班",
    "ClassCode": "0301"
},
{
    "Number": "000018",
    "Name": "学生18",
    "ClassName": "三年二班",
    "ClassCode": "0302"
}]

3、 后台数据服务实现好了,我们定义Backbone的路由服务

根据之前浏览器栏的地址的数据

http://localhost:56968/#searchByClassCode/0301

http://localhost:56968/#searchByClassCode/0302

http://localhost:56968/#searchByClassCode/all

我们定义下面的路由

searchByClassCode/:code

searchByClassCode/
对应的处理函数为getData。其中 :code为编码。
学生通过列表导航传入这些值。

<ul id="ulNav">
<li>
<a href="#searchByClassCode/all">全部</a>
</li>
<li>
<a href="#searchByClassCode/0301">三年一班</a>
</li>

<li>
<a href="#searchByClassCode/0302">三年二班</a>
</li>

<li>
<a href="#searchByClassCode/0303">三年三班</a>
</li>
<li>
<a href="#searchByClassCode/0304">三年四班</a>
</li>

</ul>

 

 

路由的实现如下

 var Route = Backbone.Router.extend({
        routes: {
            "searchByClassCode/:code": "getData",
            "searchByClassCode/": "getData"
        },
        getData: function (code) {
            stuCollection.fetch({ reset: true, data: { classCode: code} });

                $('#ulNav li').each(function (index, item) {
                    if ($(item).find("a[href$='" + code + "'").length > 0) {
                        $(this).find("a").addClass('liSelected');
                    }
                    else {
                        $(this).find("a").removeClass('liSelected');
                    }
                });
        }
    });

 

4、 路由服务定义完毕,需要把数据展示展示出来。Backbone的模型和列表

    var StuModel = Backbone.Model.extend({
        Number: "",
        Name: "",
        ClassName: ""
    });

    var StuCollection = Backbone.Collection.extend({
        model: StuModel,
        url: "/home/GetList"
    });

5、 我们实例化模型,监控模型的变化。

  var stuCollection = new StuCollection();

    var DataContentView = Backbone.View.extend({
        el: "#divContent",
        template: _.template($("#stuItem").html()),
        initialize: function () {
            this.$tableView = this.$('#tableView');
            this.listenTo(stuCollection, 'reset', this.AddAll)
        },
        AddAll: function () {
            this.$tableView.find("tbody").html("");
            stuCollection.each(this.AddOne, this);
        },
        AddOne: function (stu) {
            var a = $(this.template(stu.toJSON()));
 
            a.on("click", function () {
                if ($(this).is('.select')) {
                    $(this).removeClass("select")
                }
                else {
                    $(this).addClass("select")
                }
            })
            this.$tableView.find("tbody").append(a);
        }
    });

 其中展示部分的表格

<table id="tableView" cellpadding="5" cellspacing="5" style=" overflow:auto">
<thead>
<tr> 
<th>
学号
</th>
<th>
姓名
</th>
<th>
班级
</th>
</tr>
</thead>

<tbody></tbody>
</table>

定义的模板为

<script type="text/template" id="stuItem">
<tr>
<td><%= Number%></td>
<td><%= Name%></td>
<td><%= ClassName%></td>
</tr>
</script>

 

 下载源代码

 

 

posted on 2016-09-19 19:42  漫思  阅读(1281)  评论(0编辑  收藏  举报

导航