成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

web前端mvc庫實(shí)現(xiàn)

Kylin_Mountain / 2128人閱讀

摘要:如函數(shù)通過名,找到對(duì)應(yīng)的數(shù)組,并觸發(fā)所有數(shù)組內(nèi)回調(diào)函數(shù)。核心代碼如下效果圖源碼前端實(shí)現(xiàn)小節(jié)整篇文章基本是圍繞著如下點(diǎn),的觀察者模式的實(shí)現(xiàn)展開,期間的銷毀則取消與之有關(guān)聯(lián)對(duì)象的關(guān)系,如銷毀時(shí),注銷掉與之關(guān)聯(lián)的的回調(diào)函數(shù)。

web前端mvc庫實(shí)現(xiàn) 前言

隨著前端應(yīng)用日趨復(fù)雜,如今如angular,vue的mvvm框架,基于virtual dom的react等前端庫基本成為了各個(gè)公司的首選。而以當(dāng)初最流行的頭號(hào)大哥backbone為代表的mvc庫基本退出了歷史舞臺(tái)。

在現(xiàn)如今人人都說mvvm/react多好,backbone多差的時(shí)代。筆者看別人文章,看的時(shí)候總是感覺好像有點(diǎn)道理,看完之后如耳邊風(fēng)一般左耳朵進(jìn),右耳朵出。

so,痛定思痛之后,筆者定了個(gè)小目標(biāo),實(shí)現(xiàn)了份簡(jiǎn)易版的backbone庫。以設(shè)計(jì),實(shí)現(xiàn)的角度來對(duì)比其它類型庫的差異。

ok,廢話不多說,上正菜。

思路整理

MVC即將前端應(yīng)用抽象為Model,View,Control三大模塊。View為用戶視圖,通過瀏覽器事件接受用戶輸入。Model為數(shù)據(jù)模型,他可以隨時(shí)和后端同步數(shù)據(jù)。Control則是具體實(shí)現(xiàn)View派發(fā)的事件,計(jì)算并改變Model的數(shù)據(jù)。

UI可以被抽象為模版+數(shù)據(jù),隨著用戶不斷的觸發(fā)瀏覽器提供的各種事件,交互不斷的進(jìn)行,Control接受了View指令改變著Model的數(shù)據(jù),而View則隨著Model的改變做出響應(yīng),最終展現(xiàn)在用戶面前。

流程圖:

模塊劃分

本篇文章的思路來自于backbone,并屏棄了耦合的后端操作。早期MVC并沒有對(duì)Control做嚴(yán)格的劃分,也許是數(shù)據(jù)的改變計(jì)算并不那么復(fù)雜,所以Control功能在View的事件內(nèi)完成了,也就是說View模塊里面耦合了Control的功能。

但近幾年flux的action,store的出現(xiàn),View調(diào)用action,具體數(shù)據(jù)變化計(jì)算則在store內(nèi)部實(shí)現(xiàn),也算是把Control功能從View內(nèi)部抽象出來了吧。

Event模塊

為對(duì)象提供對(duì)事件的處理和回調(diào),內(nèi)部實(shí)現(xiàn)了觀察者(訂閱者)模式,如view訂閱了model的變化,model變化之后則通知view。

基本方法。

on函數(shù)通過event名,在object上綁定callback函數(shù),將回調(diào)函數(shù)存儲(chǔ)在數(shù)組里。

off函數(shù)移除在object上綁定的callback函數(shù)

通過event名移除指定callback。如object.off("change", onChange)

通過event名移除所有callback。如object.off("change")

移除所有指定callback。如object.off(null, onChange);

移除所有指定context的callback。如object.off(null, null, context);

清空object所有的callback。如object.off()

trigger函數(shù)通過event名,找到object對(duì)應(yīng)的數(shù)組,并觸發(fā)所有數(shù)組內(nèi)回調(diào)函數(shù)。

注意事項(xiàng)

其所有方法應(yīng)該支持類似on(name,callback),on("name1 name2 name3",callback), on({name1:callback1,name2:callback2})

這時(shí)候則可以抽象內(nèi)部公用方法。通過遞歸的方式,on({name1:callback1,name2:callback2})類型的和on("name1 name2 name3",callback)類型,最終轉(zhuǎn)化為最基本的on(name,callback)類型。核心代碼如下:

this.eventsApi = function (iteratee, name, callback, context) {
    let event;
    if (name && typeof name === "object") {
      Object.keys(name).forEach(key=> {
        event = this.eventsApi(key, name[key], context);
      })
    } else if (SEPARATE.test(name)) {
      var keys = name.split(SEPARATE);
      keys.forEach(key=> {
        event = iteratee.call(this,key, name[key], context);
      });
    } else {
      event = iteratee.call(this,name, callback, context);
    }
    return event;
};
View模塊

無狀態(tài),實(shí)例化的時(shí)候可以對(duì)應(yīng)多個(gè)model實(shí)例,并以觀察者的身份觀察這些model的變化,通過這些model數(shù)據(jù),加上指定的模版渲染dom,展示UI。

銷毀的時(shí)候注銷掉所有model的觀察,取消與相關(guān)model之間的關(guān)聯(lián)。

實(shí)例化的時(shí)候通過事件委托注冊(cè)瀏覽器事件

實(shí)現(xiàn)

_ensureElement,確保View有一層dom包裹,如果this.el這個(gè)dom不存在,則通過id,className,tagName創(chuàng)建一個(gè)dom并賦值于this.el。

listenTo,將model與view實(shí)例關(guān)聯(lián)起來,并收集關(guān)聯(lián)model,存儲(chǔ)于listenTo數(shù)組內(nèi),內(nèi)部實(shí)現(xiàn)則是調(diào)用model的on函數(shù)

stopListening,view銷毀前調(diào)用,通過listenTo數(shù)組找到關(guān)聯(lián)model,并取消view與這些model之間的觀察者關(guān)系。

$,將dom的查找定位在 this.$el下

delegateEvents,事件委托,以{"click #toggle-all": "choose"}為例,為在this.el子節(jié)點(diǎn)的id等于toggle-all的dom注冊(cè)click事件choose函數(shù)。核心代碼如下:

delegateEvents: function (events) {

   var $el = this.$el;
   Object.keys(events).forEach(item=> {
     var arr = item.split(" ");
     if (arr.length === 2) {
       var event = arr[0];
       var dom = arr[1];
       $el.on(event + ".delegateEvents" + this.$id, dom, this[events[item]].bind(this));
     }
   })
 },

undelegateEvents,注銷掉通過delegateEvents注冊(cè)的dom事件

Model模塊

Model在backbone里被抽象為object類型的Model和array類型的Collection

承載著應(yīng)用的狀態(tài),可以隨時(shí)和后端保持同步。

內(nèi)部實(shí)現(xiàn)了對(duì)數(shù)據(jù)變化的監(jiān)聽,一旦發(fā)生變化則通知觀察者View發(fā)生變化。

Model

監(jiān)聽數(shù)據(jù)的變化,對(duì)model的修改,刪除之后調(diào)用對(duì)應(yīng)的trigger函數(shù),通知訂閱了model變化的view。

set函數(shù),改變model數(shù)據(jù),并觸發(fā)change事件

set: function (obj) {
    this._changing = true;
    this.changed = obj;
    this._previousAttributes = Object.assign({}, this.attributes);
    this.attributes = Object.assign({}, this.attributes, obj);
    const keys = [];
    Object.keys(obj).forEach(key=> {
      keys.push(key);
      this.trigger("change:" + key, this);
    }, this);

    if (keys.length > 0) {
      this.trigger("change", this);
    }
    this._changing = false;
 },

destroy函數(shù)觸發(fā)destroy事件

destroy: function () {
   this.stopListening();
   this.trigger("destroy", this);
},
Collection

提供數(shù)組類型models的push,unshift,pop,shift,remove,reset等功能。push,unshift實(shí)際調(diào)用add函數(shù),pop,shift實(shí)際調(diào)用remove函數(shù)。

add函數(shù)支持任意索引插入指定數(shù)組,觸發(fā)add事件。核心的代碼如下:

    export const splice = (array, insert, at)=> {
      at = Math.max(0, Math.min(array.length, at));
      let len = insert.length;
      let tail = [];
      for (let i = at; i < array.length; i++) {
        tail.push(array[i]);
      }
      for (let i = 0; i < tail.length; i++) {
        array[i + at + len] = tail[i];
      }
      for (let i = 0; i < len; i++) {
        array[i + at] = insert[i];
      }
      return array;
    };

remove函數(shù)支持刪除指定model,觸發(fā)update事件。

_addReference,調(diào)用add方法新增model時(shí),通過觀察者模式增加該model與collection之間的關(guān)聯(lián),model的變化通知collection。核心代碼如下:

    _addReference: function (model) {
      model.on("all",this._onModelEvent,this);
     }

_removeReference,調(diào)用remove,reset移除model時(shí),取消該model與collection關(guān)聯(lián)。核心代碼如下:

    _removeReference: function(model) {
       if (this === model.collection) delete model.collection;
       model.off("all", this._onModelEvent, this);
    }
extend

生產(chǎn)環(huán)境下需要在保留原生View,Model類的功能情況下做一些業(yè)務(wù)拓展,這時(shí)候需要用到類的繼承。

雖然es6支持extend繼承,但這邊我還是手寫了一份。思路則是返回一個(gè)構(gòu)造函數(shù),該函數(shù)的原型為新的實(shí)例對(duì)象props,而props的原型對(duì)象則是父函數(shù)的原型(有點(diǎn)拗口,自己看代碼理解)。
核心代碼如下:

export const extend = function (props) {
  var parent = this;
  var child = function () {
    parent.apply(this, arguments);
  };
  child.prototype = Object.assign(Object.create(parent.prototype), props, { constructor: child });
  return child;
};
todomvc效果圖

源碼

web前端mvc實(shí)現(xiàn)

小節(jié)

整篇文章基本是圍繞著如下2點(diǎn)

view-model,collection-model的觀察者模式的實(shí)現(xiàn)展開,期間view,model的銷毀則取消與之有關(guān)聯(lián)對(duì)象的關(guān)系,如view銷毀時(shí),注銷掉與之關(guān)聯(lián)的model的回調(diào)函數(shù)。

監(jiān)聽數(shù)據(jù)變化,并通知觀察者作出響應(yīng),如model變化后觸發(fā)trigger("change")

好了,文章草草寫到這了,多謝各位看官,以上也是純個(gè)人觀點(diǎn),有問題歡迎各位web前端mvc設(shè)計(jì)指教。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/82578.html

相關(guān)文章

  • 前端練級(jí)攻略(第二部分)

    摘要:是文檔的一種表示結(jié)構(gòu)。這些任務(wù)大部分都是基于它。這個(gè)實(shí)踐的重點(diǎn)是把你在前端練級(jí)攻略第部分中學(xué)到的一些東西和結(jié)合起來。一旦你進(jìn)入框架部分,你將更好地理解并使用它們。到目前為止,你一直在使用進(jìn)行操作。它是在前端系統(tǒng)像今天這樣復(fù)雜之前編寫的。 本文是 前端練級(jí)攻略 第二部分,第一部分請(qǐng)看下面: 前端練級(jí)攻略(第一部分) 在第二部分,我們將重點(diǎn)學(xué)習(xí) JavaScript 作為一種獨(dú)立的語言,如...

    BWrong 評(píng)論0 收藏0
  • openresty 前端開發(fā)輕量級(jí)MVC框架封裝二(渲染篇)

    摘要:我們已經(jīng)用開發(fā)了版,還有微信版的應(yīng)用,已經(jīng)運(yùn)行幾個(gè)月了,很穩(wěn)定,上手也簡(jiǎn)單,開發(fā)的時(shí)候不用編譯,直接啟動(dòng)一個(gè)就搞定,部署的時(shí)候只需要幾的內(nèi)存,還可以用做各種事情,高并發(fā)防火墻,直接跑在里面,簡(jiǎn)直爽歪歪,有機(jī)會(huì)跟大家分享。示例代碼參見部分 這一章主要介紹怎么使用模板,進(jìn)行后端渲染,主要用到了lua-resty-template這個(gè)庫,直接下載下來,放到lualib里面就行了,推薦第三方庫...

    SimonMa 評(píng)論0 收藏0
  • 【譯】前端練級(jí)攻略

    摘要:由于系統(tǒng)變得越來越復(fù)雜,人們提出了稱為預(yù)處理器和后處理器的工具來管理復(fù)雜性。后處理器在由預(yù)處理器手寫或編譯后對(duì)應(yīng)用更改。我之前建議的文章,,也涵蓋了預(yù)處理器相關(guān)的知識(shí)。 譯者:前端小智 原文:medium.freecodecamp.org/from-zero-t… medium.freecodecamp.org/from-zero-t… 我記得我剛開始學(xué)習(xí)前端開發(fā)的時(shí)候。我看到了很多文章及...

    wuyumin 評(píng)論0 收藏0
  • 2014 杭JS大會(huì) 會(huì)議盛況與技術(shù)熱點(diǎn)現(xiàn)場(chǎng)報(bào)道(直播)

    摘要:中國(guó)開發(fā)者的年度盛會(huì)中國(guó)開發(fā)者大會(huì),于年月日在杭州舉辦了本年度的杭會(huì)議我們的和將為在現(xiàn)場(chǎng)為您帶來現(xiàn)場(chǎng)的報(bào)道,一覽大牛風(fēng)采,直擊技術(shù)熱點(diǎn)。簽到中第日的會(huì)議即將開幕以下是與參會(huì)者和與博文視點(diǎn)的作者們合影 中國(guó)JS開發(fā)者的年度盛會(huì)JS中國(guó)開發(fā)者大會(huì),于2014年6月21日在杭州舉辦了本年度的杭JS會(huì)議! 我們SegmentFault的 @integ 和 @shamiao 將為在現(xiàn)場(chǎng)為您帶來...

    caige 評(píng)論0 收藏0
  • 前端清單第 27 期:React Patent License 回復(fù),Shopify WebVR 購

    摘要:新聞熱點(diǎn)國(guó)內(nèi)國(guó)外,前端最新動(dòng)態(tài)就開源許可證風(fēng)波進(jìn)行回復(fù)數(shù)周前,基金會(huì)決定禁止旗下項(xiàng)目使用,因?yàn)槠湓跇?biāo)準(zhǔn)的許可證之外添加了專利聲明此舉引發(fā)了社區(qū)的廣泛討論,希望能夠更新其開源許可證。 showImg(https://segmentfault.com/img/remote/1460000010777089); 前端每周清單第 27 期:React Patent License 回復(fù),Sho...

    jeffrey_up 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<