Javascript MVC —— Model

 

原文:http://javascriptmvc.com/docs.html#&who=jQuery.Model

翻译:刘贵学([email protected])

 

模型是用于封装应用程序的数据层。对大型应用中来讲,模型是非常重要的:

  •  封装服务,这样控制层与视图不需要关心数据从哪里来;
  •  提供辅助函数,使原始的业务数据操作与抽象更简单

有两种实现方法:

  •  对服务请求或交互中获取数据;
  •  将原始的业务数据转换或封装成更有用的形式;

基本用法

jQuery.Model类提供了一个用于来组织您应用程序的数据层的基本框架。首先看一个Ajax操作不考虑模型的情况,假如我们有一个应用程序,需求如下:

  •  检索任务列表;
  •  显示每个任务的剩余天数;
  •  当用户点击后,标记完成

让我们看一下不用模型如何实现:

$.Controller.extend("MyApp.Controllers.Tasks",{onDocument: true},
{
  // 当页面加载完成时,获取所有任务 
  ready: function() {
    $.get('/tasks.json', this.callback('gotTasks'), 'json')
  },
 /* 假设json是一个数组,如:
  * [{name: "trash", due_date: 1247111409283}, ...]
  */
 gotTasks: function( json ) { 
    for(var i =0; i < json.length; i++){
      var taskJson = json[i];
 
      //计算剩余时间
      var remaininTime = new Date() - new Date(taskJson.due_date);
 
      //追加到html
      $("#tasks").append("
"+ ""+ "Due Date = "+remaininTime+"
") } }, // 用户点击,标记完成 //任务完成时, 获取id, post一个请求,删除 ".task click" : function( el ) { $.post('/tasks/'+el.attr('data-taskid')+'.json', {complete: true}, function(){ el.remove(); }) } })

此时代码看起来也还好,但如果此时:

  •  业务改变?
  •  应用的其他部分也要计算剩余时间?
  •  其他部分也要获取所有任务?
  •  同一个任务要在页面的不同地方显示?

解决方案当然是需要一个强大模型层。在学写一个model之前,让我们看一下一个漂亮的模型的控制层如何实现:

$.Controller.extend("MyApp.Controllers.Tasks",{onDocument: true},
{
  load: function() {
    Task.findAll({},this.callback('list'))
  },
  list: function( tasks ) {
    $("#tasks").html(this.view(tasks))
  },
  ".task click" : function( el ) {
    el.model().update({complete: true},function(){
      el.remove();
    });
  }
})

views/tasks/list.ejs文件内容如下:

<% for(var i =0; i < tasks.length; i++){ %>
> <%= tasks[i].timeRemaining() %>
<% } %>

这样做是不是好多了!当然,这些改善是因为我们使用了视图,同样也使我们的控制器完全可读。那让我们看一下模型:

$.Model.extend("Task",
{
 findAll: "/tasks.json",
 update: "/tasks/{id}.json"
},
{
 timeRemaining: function() {
  return new Date() - new Date(this.due_date)
 }
})

这样更好了,因为您可以在一个单独实现Ajax功能,并能在返回时封装这些数据。让我们

谈谈控制器与视图中的每个加粗项。

Task.findAll

TaskfindAll函数从"/tasks.json"请求数据,当数据返回时,先执行"wrapMany"函数后再传给成功后的回调函数。

如果你不知道回调函数如何工作,您可以看一下wrapMany callback.

el.model

jQuery.fn.model jQuery的辅助工具,它可以从html元素中返回一个模型的实例,list.ejs模板将所有的任务转为html元素,做法如下:

> ...

剩余时间timeRemaining

timeRemaining只是一个示例函数,用于封装您模型中的原始数据。

其他的好东西

以上这只是关于模型功能的一个小尝试,让我们看看下面这些特性:

封装

学会怎样与服务交互:

$.Model("Task",{
  findAll : "/tasks.json",    
  findOne : "/tasks/{id}.json", 
  create : "/tasks.json",
  update : "/tasks/{id}.json"
},{})

类型转换

"10-20-1982"的数据自动转为 new Date(1982,9,20)

$.Model("Task",{
  attributes : {birthday : "date"}
  convert : {
    date : function(raw){ ... }
  }
},{})

jQuery.Model.List

学习如何轻松处理多示例:

$.Model.List.extend("Task.List",{
  destroyAll : function(){
    var ids = this.map(function(c){ return c.id });
    $.post("/destroy",
      ids,
      this.callback('destroyed'),
      'json')
  },
  destroyed : function(){
    this.each(function(){ this.destroyed() });
  }
});
 
".destroyAll click" : function(){
  this.find('.destroy:checked')
      .closest('.task')
      .models()
      .destroyAll();
}

验证

验证你模型的属性

$.Model.extend("Contact",{
init : function(){
    this.validate("birthday",function(){
        if(this.birthday > new Date){
            return "your birthday needs to be in the past"
        }
    })
}
,{});

 

 

 

你可能感兴趣的:(javascript,mvc,function,date,任务,json)