欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

JavaScript中的View-Model使用介紹

 更新時(shí)間:2011年08月11日 06:53:42   作者:  
這是一個(gè)十分常見(jiàn)的微博列表頁(yè)面,類(lèi)似于新浪微博。上周末,在心無(wú)旁騖情況下,一共用了5個(gè)對(duì)象,產(chǎn)出400行代碼,實(shí)踐出一種代碼組織模式。
構(gòu)成
這是一個(gè)十分常見(jiàn)的微博列表頁(yè)面,類(lèi)似于新浪微博。上周末,在心無(wú)旁騖情況下,一共用了5個(gè)對(duì)象,產(chǎn)出400行代碼,實(shí)踐出一種代碼組織模式。

使任務(wù)輕松完成的代碼有4個(gè)方面的要素組成:
要素 組成
模型 Reply、Forward
視圖 CommentEditor、ReplyList、ForwardList
模板 jQuery.tmpl
異步任務(wù) jQuery.Deferred
分部介紹
模型
模型只與數(shù)據(jù)有關(guān),它能夠產(chǎn)生、過(guò)濾、保存、驗(yàn)證數(shù)據(jù),并且僅此而已。

如下例,留言模型在調(diào)用保存方法時(shí),只接收J(rèn)SON參數(shù),并且只返回一個(gè)異步任務(wù),實(shí)際處理時(shí)同步或異步的返回結(jié)果并不重要。
在此進(jìn)行的驗(yàn)證的原因是,它是一個(gè)開(kāi)放的對(duì)象,是與服務(wù)器交互的最后一道門(mén)檻。
另外,它本身也不處理驗(yàn)證失敗的情況——由視圖調(diào)用時(shí)選擇性地處理,可能會(huì)彈出一個(gè)消息提示或直接忽略再進(jìn)行重試。
復(fù)制代碼 代碼如下:

// 留言模型
var Reply = {
cache : {},
// { sourceid : id,page_size : 10,page_num : 1 }
fetch : function(data) {
return $.post('/ajax/blog/reply/list',data||{}).success(function(resp) {
resp.ok && resp.list &&
$.each(resp.list,function(k,v) {
return Reply.cache[v.id] = v;
});
});
},
// filter('name','king')
filter : function(prop,val) {
return $.grep(this.cache,function(r){ return r[prop] === val });
},
// { content : '想說(shuō)就說(shuō)',sourceid : 1001 }
create : function(data) {
// promise
var dfd = $.Deferred(), now = $.now();
if( (now - this.create.timestamp)/1000 < 10 ){
dfd.reject({message:'您發(fā)表得太快了,休息一下吧',type:'warn'})
}else if(!data || !data.sourceid){
dfd.reject({message:'非法操作',type:'error'})
}else if(!data.content){
dfd.reject({message:'評(píng)論內(nèi)容不能為空',type:'warn'})
}else{
this.create.timestamp = now;
dfd = $.post('/ajax/blog/reply/create',data);
}
return dfd.promise();
}
};
Reply.create.timestamp = Forward.create.timestamp = $.now() - 1e4;

視圖
視圖是瀏覽器頁(yè)面上的可視部分,每個(gè)視圖對(duì)象含有一個(gè)關(guān)聯(lián)的 jQuery 對(duì)象作為屬性(instance.$el),類(lèi)似于UI組件中的DOM容器。

視圖還有兩個(gè)一致的方法:

render 方法用于從模型獲取數(shù)據(jù),并且根據(jù)定義好的模板將數(shù)據(jù)渲染到HTML頁(yè)面上。
activate 方法用于激活視圖,同時(shí)綁定相關(guān)的DOM事件,所有事件至多委托到$el為止。
這個(gè)示例中,CommentEditor是父視圖,ReplyList和ForwardList是互斥顯示的兩個(gè)子視圖,父子視圖之間相互保存引用。
復(fù)制代碼 代碼如下:

// 回復(fù)列表視圖
var ReplyList = function(options) {
var opt = this.opt = $.extend({
el : '',
parent : null
},options||{});

this.parent = opt.parent;
this.$el = $(opt.el);
this.activate();
};
ReplyList.prototype = {
render : function() {
var self = this;
Reply.fetch({
page_size : 10, page_num : 1,
sourceid : self.parent.getBlogId()
})
.done(function(data) {
self.$el.html( self.$list = $.tmpl(tpl_reply_list,data) );
});
return self;
},
activate : function() {
this.$el.delegate('a.del',$.proxy(this.del,this))
}
// ...
}

// 評(píng)論編輯器視圖
CommentEditor.prototype = {
activate : function() {
this.$el.delegate('a.save',$.proxy(this.save,this))
},
save : function() {
var self = this, data = { content : self.getContent(),sourceid : self.getBlogId() };
var task_r = Reply.create(data);
var task_f = Forward.create(data);
// 轉(zhuǎn)發(fā)、評(píng)論同時(shí)進(jìn)行
$.when(task_r,task_f).then(function(t1,t2) {
// 保存成功,更新視圖或關(guān)閉
},function(data) {
// 模型驗(yàn)證出錯(cuò),或遠(yuǎn)程服務(wù)器錯(cuò)誤
Sys.info(data.message,data.type);
});
return self;
},
switchView : function(type) {
// 切換子視圖
var view_opt = {el:this.$sublist.empty(),parent:this};
if(type === 'reply'){
$label.show();
this.$submit.val('評(píng)論');
this.sublist = new ReplyList(view_opt).render();
}else{
$label.hide();
this.$submit.val('轉(zhuǎn)發(fā)');
this.sublist = new ForwardList(view_opt).render();
}
}
// ...
}

模板
模板可以消除繁瑣、丑陋的字符串拼接,它的作用是能夠直接由js對(duì)象生成HTML片斷。

模板中可以直接遍歷對(duì)象,套用預(yù)定義的函數(shù),來(lái)對(duì)一些數(shù)據(jù)進(jìn)行格式化,比如時(shí)間函數(shù)nicetime:
復(fù)制代碼 代碼如下:

// 回復(fù)列表模板
var tpl_reply_list = '<ul class="ui-reply-list">\
{{each list}}\
<li data-id="${id}">\
<a class="name" href="/${userid}">${name}:</a>\
<p>${content}</p>\
<time pubdate>${nicetime(timestamp)}</time><a class="del" href="javascript:;">刪除</a>\
</li>\
{{/each}}\
</ul>';

異步任務(wù)
Deferred Object 的直譯是延遲對(duì)象,但是理解成異步任務(wù)更為恰當(dāng)。異步任務(wù)能夠消除多層嵌套的回調(diào),讓代碼書(shū)寫(xiě)和閱讀更為便利。

從上面的模型和視圖的代碼中可以明顯地看出,使用了異步任務(wù)之后,代碼變得更加平面化了。

$.Deferred 方法新建的是一個(gè)雙向任務(wù)隊(duì)列:成功回調(diào)函數(shù)隊(duì)列和失敗回調(diào)函數(shù)隊(duì)列;任務(wù)的狀態(tài)也分為兩種:成功和失敗,分別可以用isResolved或isRejected來(lái)檢查任務(wù)的當(dāng)前狀態(tài)、用resolve或reject修改任務(wù)狀態(tài)。

promise 方法返回任務(wù)的只讀副本,此副本上不能修改任務(wù)狀態(tài)。毫無(wú)疑問(wèn),模型應(yīng)該始終只返回 promise 對(duì)象。(注:只讀副本仍然可以再次調(diào)用 promise 方法再次返回只讀副本)

在Reply.create方法中,能夠更好地處理自定義的異步任務(wù),而不是直接返回原生的ajax異步任務(wù):
復(fù)制代碼 代碼如下:

// var dfd = $.Deferred();
$.post('/ajax/blog/reply/create',data)
.success(function(json) {
if(json && json.ok){
dfd.resolve(json.list);
}else{
dfd.reject({message:json.message||'獲取失敗',type:'error'});
}
})
.fail(function() {
dfd.reject({message:'服務(wù)暫時(shí)不可用',type:'error'})
});

目的及結(jié)論
為什么拆散成這樣?

收獲:可維護(hù)性,清晰的API調(diào)用、消除二層以上的if語(yǔ)句、消除二層以上的回調(diào)語(yǔ)句、每個(gè)函數(shù)控制在二十行之內(nèi)。

結(jié)果:沒(méi)有過(guò)多的重復(fù)代碼,所有的功能都被打包好了。

相關(guān)文章

  • js隨機(jī)生成字母數(shù)字組合的字符串 隨機(jī)動(dòng)畫(huà)數(shù)字

    js隨機(jī)生成字母數(shù)字組合的字符串 隨機(jī)動(dòng)畫(huà)數(shù)字

    本篇文章給大家分享的js隨機(jī)生成字母數(shù)字組合的字符串,js隨機(jī)生成動(dòng)畫(huà)數(shù)字,包括常用的產(chǎn)生隨機(jī)數(shù)的用法,需要的朋友可以參考下
    2015-09-09
  • javaScript 連接打印機(jī),打印小票的實(shí)例

    javaScript 連接打印機(jī),打印小票的實(shí)例

    下面小編就為大家分享一篇javaScript 鏈接打印機(jī),打印小票的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2017-12-12
  • 純js代碼制作的網(wǎng)頁(yè)時(shí)鐘特效【附實(shí)例】

    純js代碼制作的網(wǎng)頁(yè)時(shí)鐘特效【附實(shí)例】

    下面小編就為大家?guī)?lái)一篇純js代碼制作的網(wǎng)頁(yè)時(shí)鐘特效【附實(shí)例】。小編覺(jué)得聽(tīng)錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2016-03-03
  • js實(shí)現(xiàn)添加刪除表格操作

    js實(shí)現(xiàn)添加刪除表格操作

    這篇文章主要為大家詳細(xì)介紹了js實(shí)現(xiàn)添加刪除表格操作,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-10-10
  • 今天是星期幾的4種JS代碼寫(xiě)法

    今天是星期幾的4種JS代碼寫(xiě)法

    這篇文章介紹了今天是星期幾的4種JS代碼寫(xiě)法,有需要的朋友可以參考一下
    2013-09-09
  • javascript實(shí)現(xiàn)模擬時(shí)鐘的方法

    javascript實(shí)現(xiàn)模擬時(shí)鐘的方法

    這篇文章主要介紹了javascript實(shí)現(xiàn)模擬時(shí)鐘的方法,涉及javascript操作時(shí)間實(shí)時(shí)顯示的相關(guān)技巧,需要的朋友可以參考下
    2015-05-05
  • 深入理解js promise chain

    深入理解js promise chain

    下面小編就為大家?guī)?lái)一篇深入理解js promise chain。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2016-05-05
  • 基于jQuery+PHP+Mysql實(shí)現(xiàn)在線(xiàn)拍照和在線(xiàn)瀏覽照片

    基于jQuery+PHP+Mysql實(shí)現(xiàn)在線(xiàn)拍照和在線(xiàn)瀏覽照片

    本文通過(guò)php jquery和mysql三者相結(jié)合,實(shí)現(xiàn)web版在線(xiàn)拍照上傳并可在線(xiàn)瀏覽,下面給大家分享基于jQuery+PHP+Mysql實(shí)現(xiàn)在線(xiàn)拍照和在線(xiàn)瀏覽照片,需要的朋友可以參考下
    2015-09-09
  • Javascript將JSON日期格式化

    Javascript將JSON日期格式化

    在做項(xiàng)目中,將實(shí)體轉(zhuǎn)化為JSON后,結(jié)果后臺(tái)返回json時(shí)間格式為/Date(1306418993027)/,在前臺(tái)JS里顯示的并不是真正的日期,而且我們不能把所有日期字段都變成string吧,因此寫(xiě)了Javascript的擴(kuò)展方法,來(lái)實(shí)現(xiàn)這個(gè)功能,代碼如下
    2016-08-08
  • js使用html2canvas實(shí)現(xiàn)屏幕截取的示例代碼

    js使用html2canvas實(shí)現(xiàn)屏幕截取的示例代碼

    這篇文章主要介紹了js使用html2canvas實(shí)現(xiàn)屏幕截取的示例代碼,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-08-08

最新評(píng)論