资讯专栏INFORMATION COLUMN

JavaScript MVC 学习笔记(六)模型之ORM

mrcode / 835人阅读

摘要:模型应当从视图和控制器中解耦出来。与数据操作和行为相关的逻辑都应当放入模型中,通过命名空间进行管理。在应用中,对象关系映射也是一种非常有用的技术,它可以用来做数据管理及用做模型。以基于的富应用开发为主要学习资料。

MVC 和命名空间

要确保应用中的视图、状态和数据彼此清晰分离,才能让架构更加整洁有序且更加健壮。模型应当从视图和控制器中解耦出来。与数据操作和行为相关的逻辑都应当放入模型中,通过命名空间
进行管理。

在JavaScript 中,通过给对象添加属性来管理一个命名空间,这个命名空间可以是函数,也可以是变量,比如:

var User = {
    records: [ /* ... */ ]
};

User 的数组数据就在命名空间User.records 中。和user 相关的函数也可以放入User 模型的命名空间里。比如用fetchRemote() 函数来从服务器端获取user 的数据:

var User = {
    records: [],
    fetchRemote: function(){ /* ... */ }
};

将模型的属性保存至命名空间中的做法可以确保不会产生冲突,这也是符合MVC 原则的,同时也能避免代码变成一堆函数和回调混杂在一起的大杂烩。

可以对命名空间做一点改进,将那些在真实user 对象上的和user 实例相关的函数也都添加进去。假设user 记录包含一个destory() 函数,它是和具体的user 相关的,因此这个函数应当基于User 实例进行调用:

var user = new User;
user.destroy()

为了做到这一点,应当将User 写成一个类,而不是一个简单对象:

var User = function(atts){
    his.attributes = atts || {};
};

User.prototype.destroy = function(){
    /* ... */
};

对于那些和具体的user 不相关的函数和变量,则可以直接定义在User 对象中:

User.fetchRemote = function(){
    /* ... */
};
构建对象关系映射(ORM)

对象关系映射(Ojbect-relational mapper,简称ORM)是在除JavaScript 以外的编程语言中常见的一种数据结构。在JavaScript 应用中,对象关系映射也是一种非常有用的技术,它可以用来做数据管理及用做模型。比如使用ORM 可以将模型和远程服务捆绑在一起,任何模型实例的改变都会在后台发起一个Ajax 请求到服务器端。或者将模型实例和HTML 元素绑定在一起,任何对实例的更改都会在界面中反映出来。

现在让来创建一个自定义ORM。

本质上讲,ORM 是一个包装了一些数据的对象层。以往ORM 常用于抽象SQL 数据库,但在这里ORM 只是用于抽象JavaScript 数据类型。这个额外的层有一个好处,可以通过给它添加自定义的函数和属性来增强基础数据的功能。比如添加数据的合法性验证、监听、数据持久化及服务器端的回调处理等,这样会增加代码的重用率。

原型继承

这里使用Object.create() 来构造ORM,这里使用基于原型(prototype-based)的继承,而没有用到构造函数和new关键字。

Object.create() 只有一个参数即原型对象,它返回一个新对象,这个新对象的原型就是传入的参数。换句话说,传入一个对象,返回一个继承了这个对象的新对象。

对于不支持的Object.create()的浏览器 ,可以很容易地模拟出这个函数:

if (typeof Object.create !== "function")
    Object.create = function(o) {
        function F() {}
        F.prototype = o;
        return new F();
    };

现在来创建Model 对象,Model 对象将用于创建新模型和实例:

var Model = {
    inherited: function(){},
    created: function(){},
    prototype: {
        init: function(){}
    },

    create: function(){
        var object = Object.create(this);
        object.parent = this;
        object.prototype = object.fn = Object.create(this.prototype);
        object.created();
        this.inherited(object);
        return object;
    },

    init: function(){
        var instance = Object.create(this.prototype);
        instance.parent = this;
        instance.init.apply(instance, arguments);
        return instance;
    }
};

create() 函数返回一个新对象,这个对象继承自Model 对象,使用它来创建新模型。
init() 函数返回一个新对象,它继承自Model.prototype——如Model 对象的一个实例:

var Asset = Model.create();
var User = Model.create();
var user = User.init();
添加ORM 属性

现在如果给Model 对象添加属性,对于继承的模型来说,这些新增属性都是可访问的:

// 添加对象属性
jQuery.extend(Model, {
    find: function(){}
});

// 添加实例属性
jQuery.extend(Model.prototype, {
    init: function(atts) {
        if (atts) this.load(atts);
    },
    load: function(attributes){
        for(var name in attributes)
        this[name] = attributes[name];
    }
});

jQuery.extend() 只是代替for 循环手动复制属性的一种快捷方式,这和在load()
函数中的做法差不多。现在,对象和实例属性都传播到了多带带的模型里:

assertEqual( typeof Asset.find, "function" );

实际上我们会增加很多属性,因此还需将extend() 和include() 添加至Model 对象中:

var Model = {
    /* ……代码片段……*/
    extend: function(o){
        var extended = o.extended;
        jQuery.extend(this, o);
        if (extended) extended(this);
    },

    include: function(o){
        var included = o.included;
        jQuery.extend(this.prototype, o);
        if (included) included(this);
    }
};

// 添加对象属性
Model.extend({
    find: function(){}
});

// 添加实例属性
Model.include({
    init: function(atts) { /* ... */ },
    load: function(attributes){ /* ... */ }
});

现在可以创建新的资源并设置一些属性:

var asset = Asset.init({name: "foo.png"});

【公开记录学习JS MVC,不知道能坚持多久= =。以《基于MVC的JavaScript web富应用开发》为主要学习资料。】

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/91480.html

相关文章

  • JavaScript MVC 学习笔记(七)模型ORM

    摘要:从技术的角度讲,出于的原因,无法友好正式地生成位的,它只能生成伪随机数。虽然中内置的方法尽管产生的是伪随机数,但也足够用了。 持久化记录 需要一种保持记录持久化的方法,即将引用保存至新创建的实例中以便任何时候都 能访问它。通过在Model 中使用records 对象来实现。当保存一个实例的时候, 就将它添加进这个对象中;当删除实例时,和将它从对象中删除: // 用来保存资源的对象 ...

    animabear 评论0 收藏0
  • JavaScript MVC 学习笔记(一)初识JS MVC

    摘要:以基于的富应用开发为主要学习资料。下面用实现一个例子使用匿名函数来封装一个作用域在页面加载时绑定事件监听上面的代码创建了控制器,这个控制器是放在变量下的命名空间。然后用了一个匿名函数封装了一个作用域,以避免对全局作用域造成污染。 公开记录学习JS MVC,不知道能坚持多久= =。以《基于MVC的JavaScript web富应用开发》为主要学习资料。 什么是MVC MVC 是一种设...

    xorpay 评论0 收藏0
  • Deep in JS - 收藏集 - 掘金

    摘要:今天同学去面试,做了两道面试题全部做错了,发过来给道典型的面试题前端掘金在界中,开发人员的需求量一直居高不下。 排序算法 -- JavaScript 标准参考教程(alpha) - 前端 - 掘金来自《JavaScript 标准参考教程(alpha)》,by 阮一峰 目录 冒泡排序 简介 算法实现 选择排序 简介 算法实现 ... 图例详解那道 setTimeout 与循环闭包的经典面...

    enali 评论0 收藏0
  • 我的Android重构旅:架构篇

    摘要:是的架构的实现。是在年提出的一种前端架构,主要用来处理复杂的逻辑的一致性问题当时是为了解决页面的消息通知问题。 去年10月底来到了新公司,刚开始接手 Android 项目时,发现该项目真的是一团遭,项目开发上没有任何架构可言,开发人员连简单的 MVC、MVP 都不了解,Activity 及其臃肿,业务边界也不明确,因此我决定重新分析一下当前主流的几种开发架构,选出适合当前项目的架构形式...

    mylxsw 评论0 收藏0
  • Backbone.js学习笔记(一)

    摘要:它通过数据模型进行键值绑定及事件处理,通过模型集合器提供一套丰富的用于枚举功能,通过视图来进行事件处理及与现有的通过接口进行交互。 本人兼职前端付费技术顾问,如需帮助请加本人微信hawx1993或QQ345823102,非诚勿扰 1.为初学前端而不知道怎么做项目的你指导 2.指导并扎实你的JavaScript基础 3.帮你准备面试并提供相关指导性意见 4.为你的前端之路提供极具建设性的...

    FrancisSoung 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<