`

JavaScriptMVC之Fixture

阅读更多

注:阅读这篇同学必须已经认识了JavaScriptMVC,否则,看起来比较困难。

$.fixture(固定物)是拦截Ajax请求并且用一个文件或者函数来模拟响应结果。当你想开发没有后台的JavaScript,它是一个很好的技术支撑。

Fixtures的类型

一般我们使用Fixtures的2种方法。第一种方法是把Ajax请求映射到一个文件。Fixtures会拦截/tasks.json请求,且把这些请求指向fixtures/tasks.json文件。
$.fixture("/tasks.json","fixtures/tasks.json");


第二种方法是把Ajax请求映射到一个函数。Fixtures会拦截/tasks/ID.json请求,且更新数据。
$.fixture("PUT /tasks/{id}.json", function(original, settings, headers){
   return { updatedAt : new Date().getTime() }
})


我们还可以把Fixtures归类为2个类型:
1、静态 - 响应是一个文件
2、动态 - 响应是靠函数生成
查找静态和动态的Fixture是方式是不同的。

静态Fixtures

静态Fixtures使用替换不同URL来响应Ajax的请求。
// looks in fixtures/tasks1.json relative to page
$.fixture("tasks/1", "fixtures/task1.json");

$.fixture("tasks/1", "//fixtures/task1.json");

动态Fixtures

动态Fixtures能获取Ajax请求且模拟服务端返回结果。
例如,从服务端返回一个成功响应的JSON数据。
$.fixture("/foobar.json", function(orig, settings, headers){
  return [200, "success", {json: {foo: "bar" } }, {} ]
})

这个Fixture函数可以使用符号表明:
function( originalOptions, options, headers ) {
  return [ status, statusText, responses, responseHeaders ]
}

当这个Fixture函数被调用用了以下参数:
originalOptions - 默认的Ajax设置项
options - 请求设置项
headers - 请求头

且把参数以数组的格式返回:

status - HTTP响应状态
statusText - HTTP响应状态文本
responses - HTTP响应结果
headers - 响应包头
然而,$.fixture处理一般的例子都是你需要一个成功响应的JSON数据。这个和之前的写法是相似的:
$.fixture("/foobar.json", function(orig, settings, headers){
  return {foo: "bar" };
})
如果你想返回一个数组数据,你可以在响应的数组中再加上其它数组。
$.fixture("/tasks.json", function(orig, settings, headers){
  return [ [ "first","second","third"] ];
})

$.fixture功能原理相似于Jquery的Ajax运作系统。想创建更好的Fixtures,理解它是一个关键。

模板匹配Urls

常常,你想一个动态的Fixture通过Urls处理多个资源(例如一个Rest Url)。$.fixture模板匹配Urls允许你用一个通配符去匹配Urls。下面的例子模拟获取和修改100个todos的服务。
// create todos
var todos = {};
for(var i = 0; i < 100; i++) {
  todos[i] = {
    id: i,
    name: "Todo "+i
  }
}
$.fixture("GET /todos/{id}", function(orig){
  // return the JSON data
  // notice that id is pulled from the url and added to data
  return todos[orig.data.id]
})
$.fixture("PUT /todos/{id}", function(orig){
  // update the todo's data
  $.extend( todos[orig.data.id], orig.data );

  // return data
  return {};
})

注意那数据是通过模板匹配Urls(ex:{id})添加到原始数据对象中。

模拟错误

下面是模拟一个未经授权请求到/foo
$.fixture("/foo", function(){
    return [401,"{type: 'unauthorized'}"]
   });

通过以下请求可以收到下面内容。
$.ajax({
  url: '/foo',
  error : function(jqXhr, status, statusText){
    // status === 'error'
    // statusText === "{type: 'unauthorized'}"
  }
})

关闭 Fixtures

你可以删除一个通过把Fixture的选项设置为null。
// add a fixture$.fixture("GET todos.json","//fixtures/todos.json");
// remove the fixture$.fixture("GET todos.json", null)//关闭特定的fixture

你还可以设置[jQuery.fixture.on $.fixture.on] 的值为false:

$.fixture.on = false;//关闭所有fixture

现在我们来重点讲解$.fixture.make,

$.fixture.make可以创建一个CRUD服务层,它还支持条件查询,排序,分组,过滤等等,
从这句话,我们就可以看到make是多强大,几乎包含了页面与后台交互的绝大部分操作。
就连Ajax超时的情况fixture也给我们考虑到了,使用$.fixture.delay来达到。

注意:在条件查询中,fixture要求我们查询的参数名称中必须包含Id或者_id,否则,查询条件不起作用。

有些同学如果使用了查询可能会发现说,只是提供了精确的查询,如果想要模糊查询怎么办?
fixture有没有提供这个功能呢,看看源代码,发现没有,但是我们又看到make最后一个参数是一个过滤器,我们是不是可以通过这个来实现呢。
实践证明,这是可以的,只是需要自己去实现这个过滤器。说到这,我们平时使用到的请求类型都几乎包含了,
大家看看有没有其它请求没有,可以提出来,大家研究研究,看看怎么去实现它。
有了这个Fixture,我们开发人员就可以使用JavaScriptMVC+Web UI Plugin来开发Web项目的高保真了,而且是比较真实的demo。

让我们一起来完成演示例子,以后,我们就可以根据这个例子来构造自己项目的Fixtures。

下面让我一步一步讲解如何在项目到构造和使用Fixtures。
创建项目
在这里,我把下载的MVC包放到本地的E:\jQuery\javascriptmvc这个目录,使用DOC命令,进入到E:\jQuery\javascriptmvc这个目录下,
执行js jquery/generate/app cookbook命令,生成工程,
执行命令后,我们在E:\jQuery\javascriptmvc目录下看到生成的cookbook文件夹,这就是我们创建的工程,然后我们再在这个工程下面创建一个模块message,执行命令:js jquery/generate/scaffold Cookbook.Models.Message,
我们打开cookbook文件夹,看到文件夹下面有一个message文件夹,
这就是我们生成的message模块,而且我们还看到一个fixtures文件夹,我们写的fixture就是在这个文件夹下的fixtures.js文件。
接着修改cookbook.html,如下:
<!DOCTYPE HTML>
<html lang="en">
    <head>
        <title>cookbook</title>
    </head>
    <body>
    <body>
        //把多余的代码删除,添加下面2条代码
        <ul id='messages'></ul>//显示message列表的元素
        <form id='create' action=''></form>//创建message使用到的元素
       
        <script type='text/javascript'
                src='../steal/steal.js?cookbook'>  
        </script>
    </body>
    </body>
</html>
接着打开cookbook.html,我们可以看到生成的代码已经具有删除,创建,显示所有message的功能。
但是没有以下功能:修改,条件精确查询,条件模糊查询,分组,排序等。

修改:
其实修改功能已经存在,只是页面上没有体现出来,现在我们给页面上添加上修改的功能。
修改E:\jQuery\javascriptmvc\cookbook\message\list\views\message.ejs文件,添加修改功能的触发元素源。最终代码如下:
<h3><%= name %> <a href='javascript://' class='destroy'>X</a>
<a href='javascript://' class='update'>U</a>//这句是我们添加的代码,点击它可以起到修改的功能
</h3>
<p><%= description %></p>
接着我们来修改controller:E:\jQuery\javascriptmvc\cookbook\message\list\list.js文件,最终代码如下:
steal( 'jquery/controller',
       'jquery/view/ejs',
       'jquery/controller/view',
       'cookbook/models' )
.then( './views/init.ejs',
       './views/message.ejs',
       function($){

/**
 * @class Cookbook.Message.List
 * @parent index
 * @inherits jQuery.Controller
 * Lists messages and lets you destroy them.
 */
$.Controller('Cookbook.Message.List',
/** @Static */
{
    defaults : {}
},
/** @Prototype */
{
    init : function(){
        //这句就是我们后续需要添加查询功能的语句,我们会不段修改这句来达到各种查询的效果
        this.element.html(this.view('init',Cookbook.Models.Message.findAll()) )
    },
    '.destroy click': function( el ){
        if(confirm("Are you sure you want to destroy?")){
            el.closest('.message').model().destroy();
        }
    },
    //这个是我们添加的触发修改功能的函数,我们把这个记录的name的值修改为test
    '.update click':function(el){
        el.closest('.message').model().update({name:'test'});
    },
    "{Cookbook.Models.Message} destroyed" : function(Message, ev, message) {
        message.elements(this.element).remove();
    },
    "{Cookbook.Models.Message} created" : function(Message, ev, message){
        this.element.append(this.view('init', [message]))
    },
    "{Cookbook.Models.Message} updated" : function(Message, ev, message){
        message.elements(this.element)
              .html(this.view('message', message) );
    }
});
});
条件精确查询:
修改E:\jQuery\javascriptmvc\cookbook\models\message.js文件,最终代码如下:
steal('jquery/model', function(){

/**
 * @class Cookbook.Models.Message
 * @parent index
 * @inherits jQuery.Model
 * Wraps backend message services. 
 */
$.Model('Cookbook.Models.Message',
/* @Static */
{
    /**
    * 代码修改点
    */
    findAll: function(attr,success,error){
        return $.ajax({
            url:'messages',
            type:'get',
            dataType:'json message.models',//这句message.models很重要,因为这个是把影响回来的数据model化
            success:success,
            error:error,
            data:attr,
            fixture:'-messages'//指定ajax发送到fixture的messages中
        });
    },
      findOne : "/messages/{id}.json",
      create : "/messages.json",
     update : "/messages/{id}.json",
      destroy : "/messages/{id}.json"
},
/* @Prototype */
{});
})
用浏览器打开cookbook.html,突然发现之前一起显示的列表,现在没有了,看看浏览器的日志,我们看到no fixture found。说明上面的messages没有找到。
现在就到我们修改fixtures.js文件的时候了,最终代码如下:
// map fixtures for this application
steal("jquery/dom/fixture", function(){
    $.fixture.make(["messages","message"], 10, function(i, messages){
        var descriptions = ["grill fish", "make ice", "cut onions"]
        return {
            name: "message "+i,
            msg_id:'msg_'+i,//精确查询功能
            msgId:'msg'+i,//精确查询功能
            description: $.fixture.rand( descriptions , 1)[0]
        }
    }
})
我们可以通过msg_id或者msgId来精确查询记录,有没有发现一个很奇怪的现象就是这些可以精确查询字段都是_id或者Id才可以。
原来,fixture提供的精确查询条件字段一定要包含_id或者Id,否则,不能查询,像上面的name,description都不可以,除非我们修改fixture中的源码。

接着修改list.js文件中的这句代码:
//这句就是我们后续需要添加查询功能的语句,我们会不段修改这句来达到各种查询的效果
this.element.html(this.view('init',Cookbook.Models.Message.findAll()) )
修改成如下:
        this.element.html(this.view('init',Cookbook.Models.Message.findAll({
            msg_id:'msg_1'
        })) )       
当然我们还可以添加msgId这个查询条件。
在这里我们还需要提到的一个就是fixture默认提供的一个分页查询参数,offset(从那条记录起)和limit(第页记录数)。 修改上面代码如下:
        this.element.html(this.view('init',Cookbook.Models.Message.findAll({
            offset:0,
            limit:5
        })) );
我们可以看到10记录,只显示了5条,这个就是分页的模拟结果了。
排序,分组功能:
这2个功能相似,所以放到一起讲,因为它们所达到的效果其实差不多。fixture提供2个查询参数来达到,order和group。
我们修改查询代码(list.js),代码如下:
        this.element.html(this.view('init',Cookbook.Models.Message.findAll({
            order:["description asc"]
        })) )
看看效果,再修改这个代码如下:
        this.element.html(this.view('init',Cookbook.Models.Message.findAll({
            group:["description"]
        })) )
看看效果,是不是和上面的差不多。
条件模糊查询:
我们只需要修改fixture.js就可以达到这个效果,查看fixture的API,我们看到$.fixture.make最后面的一个参数是一个过滤函数,我们就拿这个函数
来完成模糊查询的功能,修改代码如下:
// map fixtures for this application

steal("jquery/dom/fixture", function(){
    $.fixture.make(["messages","message"], 10, function(i, messages){
        var descriptions = ["grill fish", "make ice", "cut onions"]
        return {
            name: "message "+i,
            msg_id:'msg_'+i,//精确查询功能
            msgId:'msg'+i,//精确查询功能
            description: $.fixture.rand( descriptions , 1)[0]
        }
    },
    /**
    * 过滤器,完成模糊查询功能
    * 模糊查询description字段中包含make文本的记录
    */
    function(item,settings){
        if(item.description.indexOf(settings.data.description)>-1){
            return item;
        }
    }
    )
})
再次修改查询条件(list.js),代码如下:
        this.element.html(this.view('init',Cookbook.Models.Message.findAll({
            description:'make'
        })) );
我们就记记录集中的make模糊查询出来。

至此,我们所需要讲的使用fixture来模拟我们所需要的Ajax请求和影响已经讲完。

2
0
分享到:
评论

相关推荐

    JavaScriptMVC之实战

    NULL 博文链接:https://lyndon-lin.iteye.com/blog/1556095

    javascriptmvc3.0.5

    上传了一半的javascriptmvc3.0.5,这个是【下】

    javascriptmvc-3.3.zip

    JavaScriptMVC是一个全面的JavaScript应用程序开发框架,专注于构建大型、可维护的前端应用。这个压缩包"javascriptmvc-3.3.zip"包含了该框架的3.3版本。JavaScriptMVC以其模块化、可测试和高性能的特点,深受开发者...

    MVC框架 JavaScriptMVC.zip

    JavaScriptMVC是一个强大的JavaScript MVC(Model-View-Controller)框架,专为构建复杂且高性能的前端Web应用而设计。这个框架旨在提供一套完整的工具集,包括数据管理、视图渲染、路由控制以及测试支持,从而使得...

    javaScriptMVC 开源框架 第一部分

    JavaScriptMVC是一个强大的前端开发框架,它以JavaScript为核心,结合了Model-View-Controller(MVC)设计模式,旨在提供一套完整的解决方案,帮助开发者构建高效、可维护的Web应用程序。这个开源项目是基于jQuery和...

    javascriptmvc-3.2.4.zip

    JavaScriptMVC是一个全面的JavaScript开发框架,专注于构建大型、可维护的前端应用。这个3.2.4版本的压缩包包含了一系列工具和库,旨在帮助开发者遵循Model-View-Controller(MVC)设计模式,提高代码组织和项目管理...

    从JavaScriptMVC开始如何完成项目之压缩文件和生成帮助文档

    在“从JavaScriptMVC开始如何完成项目之压缩文件和生成帮助文档”这个主题中,我们将探讨如何利用该框架进行项目开发,特别是涉及到的压缩文件处理和生成帮助文档这两个关键环节。 一、压缩文件 在项目开发中,压缩...

    从JavaScriptMVC开始如何完成项目之创建应用程序

    这篇博客文章“从JavaScriptMVC开始如何完成项目之创建应用程序”可能是指导开发者如何使用特定的JavaScript MVC框架或库来构建一个完整的应用程序。 在JavaScript MVC中: 1. **模型(Model)**:负责处理和管理...

    javascriptmvc

    JavaScript MVC(Model-View-Controller)是一种用于构建前端Web应用程序的架构模式,灵感来源于Java的MVC框架。这种模式在JavaScript开发中广泛采用,旨在提高代码的组织性、可维护性和可扩展性。...

    javascriptmvc-3.0.5最新包

    javascriptmvc3.0.5,文件大于20MB,分成两个卷

    JavaScriptMVC框架Mithril.zip

    Mithril.js 是一个客户端的 JavaScript MVC 框架。可将应用分成数据层、UI层和控制层。Mithril 压缩后只有 3kb 左右。API 提供一个模板引擎,带 DOM diff 实现,支持路由和组合。 示例代码: ...

    谈谈JavaScriptMVC模式共3页.pdf.zip

    JavaScript MVC模式是Web开发中的一种架构模式,它用于组织和管理复杂的前端应用。MVC,即Model-View-Controller,是一种设计模式,旨在分离应用程序的数据层(Model)、用户界面层(View)和控制逻辑层(Controller...

    javaScriptMVC 开源框架 第二部分

    JavaScript MVC开源框架是一种用于构建富前端应用的框架,它整合了多种JavaScript库和技术,如jQuery,使得开发者可以更高效地组织和管理前端代码,实现Model-View-Controller(MVC)设计模式。...

    JavaScriptMVC:JavaSriptMVC 高级编程课程

    JavaScriptMVC是一个全面的前端开发框架,专注于使用JavaScript进行复杂应用程序的构建。它结合了Model-View-Controller(MVC)的设计模式,提供了一整套工具和服务,旨在提高开发效率和代码可维护性。在这个高级...

    JavascriptMVC代码

    JavaScript MVC(Model-View-Controller)是一种用于构建前端应用程序的架构模式,它借鉴了传统的后端MVC设计模式,以帮助开发者组织和管理复杂的JavaScript应用。在这个架构中,Model负责数据处理,View负责用户...

    javaScriptMVC 开源框架 第三部分(相关资料和例子)

    在"javascriptMVC 相关资料.docx"文档中,可能会包含以下知识点: 1. **MVC概念**:解释模型(Model)、视图(View)和控制器(Controller)的基本职责。模型处理数据和业务逻辑,视图负责用户界面的展示,而控制器...

    JavaScriptMVC框架PK:Angular、Backbone、CanJS与Ember

    :选择JavaScriptMVC框架很难。一方面要考虑的因素非常多,另一方面这种框架也非常多,而要从中选择一个合适的,还真得费一番心思。本文对JavaScriptMVC框架Angular、Backbone、CanJS和Ember作了比较,供大家参考。...

    JavaScriptMVC 测试框架 v2.2

    内容索引:脚本资源,Ajax/JavaScript,JavaScriptMVC JavaScriptMVC 是一个功能强大的 JavaScript framework. 也是一个很棒的JavaScript测试框架,它同样能提高开发的速度。JavaScriptMVC应用了模型-视图-控制器架构...

Global site tag (gtag.js) - Google Analytics