JavaScript MVC 进修笔记(七)模子之ORM

耐久化纪录

须要一种对峙纪录耐久化的要领,行将援用保留至新建立的实例中以便任何时刻都
能接见它。经由过程在Model 中运用records 对象来完成。当保留一个实例的时刻,
就将它添加进这个对象中;当删除实例时,和将它从对象中删除:

// 用来保留资本的对象
Model.records = {};
    Model.include({
        newRecord: true,
        create: function(){
        this.newRecord = false;
        this.parent.records[this.id] = this;
    },
    destroy: function(){
        delete this.parent.records[this.id];
    }
});

更新一个已存在的实例——只需更新对象援用即可:

Model.include({
    update: function(){
        this.parent.records[this.id] = this;
    }
});

如今建立一个快速函数来保留实例,如许就不必每次都搜检这个实例是不是已保留过或
是不是须要新建立实例了:

// 将对象存入hash 纪录中,对峙一个援用指向它
Model.include({
    save: function(){
        this.newRecord ? this.create() : this.update();
    }
});

用来依据ID 查找资本的find() 函数:

Model.extend({
    // 经由过程ID 查找,找不到则抛出非常
    find: function(id){
        return this.records[id] || throw("Unknown record");
    }
});

如今已成功地建立了一个基础的ORM,运转一下:

var asset = Asset.init();
asset.name = "same, same";
asset.id = 1
asset.save();
var asset2 = Asset.init();
asset2.name = "but different";
asset2.id = 2;
asset2.save();
assertEqual( Asset.find(1).name, "same, same" );
asset2.destroy();

增添 ID 支撑

此时每次保留一条纪录都必须手动指定一个ID。能够到场自动化处置惩罚。起首,我们须要一个要领来自动天生ID,能够运用全局一致标识(Globally UniqueIdentifier,简称GUID)天生器来做这一步。从手艺的角度讲,出于API 的缘由,JavaScript 没法友爱正式地天生128 位的GUID,它只能天生伪随机数。虽然JavaScript 中内置的Math.random() 要领只管发生的是伪随机数,但也充足用了。

Robert Kieffer 写了一个简单明了的GUID 天生器,它运用Math.random() 来发生一个伪
随机数的GUID(http://goo.gl/0b0hu),代码也很简单:

Math.guid = function(){
    return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
        var r = Math.random()*16|0, v = c == 'x' ? r : (r&0x3|0x8);
        return v.toString(16);
    }).toUpperCase();
};

如今有了天生GUID 的要领,能够很轻易将它集成到ORM 里,剩下的只需修正
create() 函数了:

Model.extend({
    create: function(){
        if ( !this.id ) 
            this.id = Math.guid();
        this.newRecord = false;
        this.parent.records[this.id] = this;
    }
});

如许任何新建立的纪录都包括一个随机的GUID 作为它们的ID :

var asset = Asset.init();
asset.save();
asset.id //=> "54E52592-313E-4F8B-869B-58D61F00DC74"

寻址援用

现在建立的ORM 中存在一个与援用相干的bug。当保留或
经由过程find() 查找纪录时,所返回的实例并没有复制一份,因而对任何属性的修正都邑影
响原始资本。革新:

var asset = new Asset({name: "foo"});
asset.save();

// 准确传入资本
assertEqual( Asset.find(asset.id).name, "foo" );

// 变动属性,而没有挪用update()
asset.name = "wem";

// 出题目了,由于asset 的名字被修正为“wem”
assertEqual( Asset.find(asset.id).name, "foo" );

须要修复这个题目,在实行find() 操纵的时刻新建立一个对象,同样在建立或更新
纪录的时刻须要复制对象:

Asset.extend({
    find: function(id){
        var record = this.records[id];
        if ( !record ) throw("Unknown record");
        return record.dup();
    }
    });
    Asset.include({
        create: function(){
        this.newRecord = false;
        this.parent.records[this.id] = this.dup();
    },
    update: function(){
        this.parent.records[this.id] = this.dup();
    },
    dup: function(){
        return jQuery.extend(true, {}, this);
    }
});

这里存在别的一个题目,Model.records 是被一切模子所同享的对象:

assertEqual( Asset.records, Person.records );

但这在兼并一切的纪录时会有副作用:

var asset = Asset.init();
asset.save();
assert( asset in Person.records );

解决办法是在建立新的模子时设置一个新的records 对象。Model.create() 是建立新对
象的回调,因而我们能够设置恣意形貌这个模子的对象:

Model.extend({
    created: function(){
        this.records = {};
    }
});

【公然纪录进修JS MVC,不知道能对峙多久= =。以《基于MVC的JavaScript web富运用开辟》为重要进修材料。】

    原文作者:JingDing
    原文地址: https://segmentfault.com/a/1190000002606967
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞