摘要:模型應(yīng)當(dāng)從視圖和控制器中解耦出來。與數(shù)據(jù)操作和行為相關(guān)的邏輯都應(yīng)當(dāng)放入模型中,通過命名空間進(jìn)行管理。在應(yīng)用中,對象關(guān)系映射也是一種非常有用的技術(shù),它可以用來做數(shù)據(jù)管理及用做模型。以基于的富應(yīng)用開發(fā)為主要學(xué)習(xí)資料。
MVC 和命名空間
要確保應(yīng)用中的視圖、狀態(tài)和數(shù)據(jù)彼此清晰分離,才能讓架構(gòu)更加整潔有序且更加健壯。模型應(yīng)當(dāng)從視圖和控制器中解耦出來。與數(shù)據(jù)操作和行為相關(guān)的邏輯都應(yīng)當(dāng)放入模型中,通過命名空間
進(jìn)行管理。
在JavaScript 中,通過給對象添加屬性來管理一個命名空間,這個命名空間可以是函數(shù),也可以是變量,比如:
var User = { records: [ /* ... */ ] };
User 的數(shù)組數(shù)據(jù)就在命名空間User.records 中。和user 相關(guān)的函數(shù)也可以放入User 模型的命名空間里。比如用fetchRemote() 函數(shù)來從服務(wù)器端獲取user 的數(shù)據(jù):
var User = { records: [], fetchRemote: function(){ /* ... */ } };
將模型的屬性保存至命名空間中的做法可以確保不會產(chǎn)生沖突,這也是符合MVC 原則的,同時也能避免代碼變成一堆函數(shù)和回調(diào)混雜在一起的大雜燴。
可以對命名空間做一點改進(jìn),將那些在真實user 對象上的和user 實例相關(guān)的函數(shù)也都添加進(jìn)去。假設(shè)user 記錄包含一個destory() 函數(shù),它是和具體的user 相關(guān)的,因此這個函數(shù)應(yīng)當(dāng)基于User 實例進(jìn)行調(diào)用:
var user = new User; user.destroy()
為了做到這一點,應(yīng)當(dāng)將User 寫成一個類,而不是一個簡單對象:
var User = function(atts){ his.attributes = atts || {}; }; User.prototype.destroy = function(){ /* ... */ };
對于那些和具體的user 不相關(guān)的函數(shù)和變量,則可以直接定義在User 對象中:
User.fetchRemote = function(){ /* ... */ };構(gòu)建對象關(guān)系映射(ORM)
對象關(guān)系映射(Ojbect-relational mapper,簡稱ORM)是在除JavaScript 以外的編程語言中常見的一種數(shù)據(jù)結(jié)構(gòu)。在JavaScript 應(yīng)用中,對象關(guān)系映射也是一種非常有用的技術(shù),它可以用來做數(shù)據(jù)管理及用做模型。比如使用ORM 可以將模型和遠(yuǎn)程服務(wù)捆綁在一起,任何模型實例的改變都會在后臺發(fā)起一個Ajax 請求到服務(wù)器端。或者將模型實例和HTML 元素綁定在一起,任何對實例的更改都會在界面中反映出來。
現(xiàn)在讓來創(chuàng)建一個自定義ORM。
本質(zhì)上講,ORM 是一個包裝了一些數(shù)據(jù)的對象層。以往ORM 常用于抽象SQL 數(shù)據(jù)庫,但在這里ORM 只是用于抽象JavaScript 數(shù)據(jù)類型。這個額外的層有一個好處,可以通過給它添加自定義的函數(shù)和屬性來增強基礎(chǔ)數(shù)據(jù)的功能。比如添加數(shù)據(jù)的合法性驗證、監(jiān)聽、數(shù)據(jù)持久化及服務(wù)器端的回調(diào)處理等,這樣會增加代碼的重用率。
原型繼承這里使用Object.create() 來構(gòu)造ORM,這里使用基于原型(prototype-based)的繼承,而沒有用到構(gòu)造函數(shù)和new關(guān)鍵字。
Object.create() 只有一個參數(shù)即原型對象,它返回一個新對象,這個新對象的原型就是傳入的參數(shù)。換句話說,傳入一個對象,返回一個繼承了這個對象的新對象。
對于不支持的Object.create()的瀏覽器 ,可以很容易地模擬出這個函數(shù):
if (typeof Object.create !== "function") Object.create = function(o) { function F() {} F.prototype = o; return new F(); };
現(xiàn)在來創(chuàng)建Model 對象,Model 對象將用于創(chuàng)建新模型和實例:
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() 函數(shù)返回一個新對象,這個對象繼承自Model 對象,使用它來創(chuàng)建新模型。
init() 函數(shù)返回一個新對象,它繼承自Model.prototype——如Model 對象的一個實例:
var Asset = Model.create(); var User = Model.create(); var user = User.init();添加ORM 屬性
現(xiàn)在如果給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 循環(huán)手動復(fù)制屬性的一種快捷方式,這和在load()
函數(shù)中的做法差不多?,F(xiàn)在,對象和實例屬性都傳播到了多帶帶的模型里:
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){ /* ... */ } });
現(xiàn)在可以創(chuàng)建新的資源并設(shè)置一些屬性:
var asset = Asset.init({name: "foo.png"});
【公開記錄學(xué)習(xí)JS MVC,不知道能堅持多久= =。以《基于MVC的JavaScript web富應(yīng)用開發(fā)》為主要學(xué)習(xí)資料。】
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/91480.html
摘要:從技術(shù)的角度講,出于的原因,無法友好正式地生成位的,它只能生成偽隨機數(shù)。雖然中內(nèi)置的方法盡管產(chǎn)生的是偽隨機數(shù),但也足夠用了。 持久化記錄 需要一種保持記錄持久化的方法,即將引用保存至新創(chuàng)建的實例中以便任何時候都 能訪問它。通過在Model 中使用records 對象來實現(xiàn)。當(dāng)保存一個實例的時候, 就將它添加進(jìn)這個對象中;當(dāng)刪除實例時,和將它從對象中刪除: // 用來保存資源的對象 ...
摘要:以基于的富應(yīng)用開發(fā)為主要學(xué)習(xí)資料。下面用實現(xiàn)一個例子使用匿名函數(shù)來封裝一個作用域在頁面加載時綁定事件監(jiān)聽上面的代碼創(chuàng)建了控制器,這個控制器是放在變量下的命名空間。然后用了一個匿名函數(shù)封裝了一個作用域,以避免對全局作用域造成污染。 公開記錄學(xué)習(xí)JS MVC,不知道能堅持多久= =。以《基于MVC的JavaScript web富應(yīng)用開發(fā)》為主要學(xué)習(xí)資料。 什么是MVC MVC 是一種設(shè)...
摘要:今天同學(xué)去面試,做了兩道面試題全部做錯了,發(fā)過來給道典型的面試題前端掘金在界中,開發(fā)人員的需求量一直居高不下。 排序算法 -- JavaScript 標(biāo)準(zhǔn)參考教程(alpha) - 前端 - 掘金來自《JavaScript 標(biāo)準(zhǔn)參考教程(alpha)》,by 阮一峰 目錄 冒泡排序 簡介 算法實現(xiàn) 選擇排序 簡介 算法實現(xiàn) ... 圖例詳解那道 setTimeout 與循環(huán)閉包的經(jīng)典面...
摘要:是的架構(gòu)的實現(xiàn)。是在年提出的一種前端架構(gòu),主要用來處理復(fù)雜的邏輯的一致性問題當(dāng)時是為了解決頁面的消息通知問題。 去年10月底來到了新公司,剛開始接手 Android 項目時,發(fā)現(xiàn)該項目真的是一團遭,項目開發(fā)上沒有任何架構(gòu)可言,開發(fā)人員連簡單的 MVC、MVP 都不了解,Activity 及其臃腫,業(yè)務(wù)邊界也不明確,因此我決定重新分析一下當(dāng)前主流的幾種開發(fā)架構(gòu),選出適合當(dāng)前項目的架構(gòu)形式...
摘要:它通過數(shù)據(jù)模型進(jìn)行鍵值綁定及事件處理,通過模型集合器提供一套豐富的用于枚舉功能,通過視圖來進(jìn)行事件處理及與現(xiàn)有的通過接口進(jìn)行交互。 本人兼職前端付費技術(shù)顧問,如需幫助請加本人微信hawx1993或QQ345823102,非誠勿擾 1.為初學(xué)前端而不知道怎么做項目的你指導(dǎo) 2.指導(dǎo)并扎實你的JavaScript基礎(chǔ) 3.幫你準(zhǔn)備面試并提供相關(guān)指導(dǎo)性意見 4.為你的前端之路提供極具建設(shè)性的...
閱讀 881·2021-11-22 09:34
閱讀 1016·2021-10-08 10:16
閱讀 1832·2021-07-25 21:42
閱讀 1798·2019-08-30 15:53
閱讀 3531·2019-08-30 13:08
閱讀 2190·2019-08-29 17:30
閱讀 3351·2019-08-29 17:22
閱讀 2184·2019-08-29 15:35