摘要:寫給讀者的話本人是千千萬萬前端小白中的一員,所以對前端小白的痛苦感同身受,面對一個新的知識點,很多時候感到束手無策。
寫給讀者的話
本人是千千萬萬前端小白中的一員,所以對前端小白的痛苦感同身受,面對一個新的知識點,很多時候感到束手無策。網上搜資料,有的不全,有的看不懂,所以本人作為小白,很有義務將自己覺得理解了的知識點盡可能的解釋的通熟易懂,恨不得一個字一個字的解釋。但是別人的終究是別人的,把它變成自己的才是正道,希望此文能幫助像我一樣的人更好的理解mvc,一起加油吧
先上demo代碼,下面有詳盡分析index.js
function Event(sender) { this._sender = sender; this._listeners = []; } Event.prototype = { constructor : Event, attach: function (listener) { this._listeners.push(listener); }, notify: function (args) { var index; for (index = 0; index < this._listeners.length; index += 1) { this._listeners[index](this._sender, args); } } }; function ListModel(items) { this._items = items; this._selectedIndex = -1; this.itemAdded = new Event(this); this.itemRemoved = new Event(this); this.selectedIndexChanged = new Event(this); } ListModel.prototype = { constructor : ListModel, getItems: function () { return [].concat(this._items); }, addItem: function (item) { this._items.push(item); this.itemAdded.notify({ item: item }); }, removeItemAt: function (index) { var item; item = this._items[index]; this._items.splice(index, 1); this.itemRemoved.notify({ item: item }); if (index === this._selectedIndex) { this.setSelectedIndex(-1); } }, getSelectedIndex: function () { return this._selectedIndex; }, setSelectedIndex: function (index) { var previousIndex; previousIndex = this._selectedIndex; this._selectedIndex = index; this.selectedIndexChanged.notify({ previous: previousIndex }); } }; function ListView(model, elements) { this._model = model; this._elements = elements; this.listModified = new Event(this); this.addButtonClicked = new Event(this); this.delButtonClicked = new Event(this); var _this = this; // attach model listeners this._model.itemAdded.attach(function () { _this.rebuildList(); }); this._model.itemRemoved.attach(function () { _this.rebuildList(); }); // attach listeners to HTML controls this._elements.list.change(function (e) { _this.listModified.notify({ index: e.target.selectedIndex }); }); this._elements.addButton.click(function () { _this.addButtonClicked.notify(); }); this._elements.delButton.click(function () { _this.delButtonClicked.notify(); }); } ListView.prototype = { constructor : ListView, show: function () { this.rebuildList(); }, rebuildList: function () { var list, items, key; list = this._elements.list; list.html(""); items = this._model.getItems(); for (key in items) { if (items.hasOwnProperty(key)) { list.append($("")); } } this._model.setSelectedIndex(-1); } }; function ListController(model, view) { this._model = model; this._view = view; var _this = this; this._view.listModified.attach(function (sender, args) { _this.updateSelected(args.index); }); this._view.addButtonClicked.attach(function () { _this.addItem(); }); this._view.delButtonClicked.attach(function () { _this.delItem(); }); } ListController.prototype = { constructor : ListController, addItem: function () { var item = window.prompt("Add item:", ""); if (item) { this._model.addItem(item); } }, delItem: function () { var index; index = this._model.getSelectedIndex(); if (index !== -1) { this._model.removeItemAt(this._model.getSelectedIndex()); } }, updateSelected: function (index) { this._model.setSelectedIndex(index); } }; $(function () { var model = new ListModel(["PHP", "JavaScript"]), view = new ListView(model, { "list": $("#list"), "addButton": $("#plusBtn"), "delButton": $("#minusBtn") }), controller = new ListController(model, view); view.show(); });
index.html
MVC模式說明:MVC
針對代碼做具體分析:model層和view層都繼承了觀察者類,觀察者類中包含訂閱和發布方法
model層定義了底層操作,包括對數據的增刪改查
view層綁定了增刪改事件,一旦所綁定的事件發生,就調用觀察者類中的發布方法發布消息;同時又訂閱了model層數據的變動,一旦所訂閱的model層的數據發生變化,就調用view層自身方法更新數據顯示
controller層訂閱了view層的增刪改事件,一旦所訂閱的事件發布了,就調用自身的方法經過業務邏輯的處理,調用相應的model層的方法
見下圖:
首先頁面加載執行初始化代碼,執行完成后頁面上會有一個列表,里面包含兩個選項:PHP和Javascript,然后底下有"+"和"-"兩個按鈕,以點擊"+"為例,流程分析開始:
首先定義了一個觀察者Event構造函數
view層中綁定了增刪改事件,同時訂閱了model層數據改動事件;
我們點擊"+"號按鈕,觸發了view層中的addButton的click事件,然后addButtonClicked調用觀察者構造函數的發布方法notify()發布消息,代碼如下:
this._elements.addButton.click(function () { _this.addButtonClicked.notify(); });
4.由于在controller層中訂閱了view層的addButtonClicked發布的消息,將addItem()保存在其對應的listener數組中,所以此時執行_this.addItem(),代碼如下:
this._view.addButtonClicked.attach(function () { _this.addItem(); });
5.在controller層中的addItem()方法中,如果有item輸入,就調用model層中的addItem(item)并傳入item,代碼如下:
addItem: function () { var item = window.prompt("Add item:", ""); if (item) { this._model.addItem(item); } }
6.在model層中的itemAdd()方法中,獲取到controller層中傳過來的item之后,將其保存到this.item數組中,然后model層中的item調用notify()發布消息,代碼如下:
addItem: function (item) { this._items.push(item); this.itemAdded.notify({ item: item }); }
7.由于在view層中訂閱了model層的itemAdd發布的消息,將rebuildList()保存在其對應的listener數組中,所以此時執行_this.rebuildList(),代碼如下:
this._model.itemAdded.attach(function () { _this.rebuildList(); });
8.view層中的rebuildList()干的事情就是每次都先清空列表內容,然后重新獲取內容,再循環添加到列表中,最后調用model層中的setSelectedIndex(-1)把選中項的index還原為-1,代碼如下:
rebuildList: function () { var list, items, key; list = this._elements.list; list.html(""); items = this._model.getItems(); for (key in items) { if (items.hasOwnProperty(key)) { list.append($("")); } } this._model.setSelectedIndex(-1); }
9.model層中的setSelectedIndex()干的事情就是把上一次的選中項的index和當前選中項的index進行交換,然后model層中的selectedIndexChanged調用notify()發布消息,代碼如下:
setSelectedIndex: function (index) { var previousIndex; previousIndex = this._selectedIndex; this._selectedIndex = index; this.selectedIndexChanged.notify({ previous: previousIndex }); }
MVC的優點:10.你會發現view層中沒有對selectedIndexChanged的訂閱,那寫起來干嘛呢?就是留著以后進行擴展用的,你可以繼續按照這個模式寫下去
耦合性低:視圖層和業務層分離了,如果頁面上顯示改變的話,直接在視圖層更改即可,不用動模型層和控制層上的代碼;也就是視圖層 與 模型層和控制層
已經分離了;所以很容易改變應用層的數據層和業務規則。
可維護性:分離視圖層和業務邏輯層也使得WEB應用更易于維護和修改。
MVC的缺點:個人覺得適合于大型項目,對于中小型項目并不適合,因為要實現一個簡單的增刪改操作,只需要一點點JS代碼,但是MVC模式代碼量明顯增加了。
希望此文對你有幫助,如有疑問和錯誤,請告訴我,謝謝!
參考資料:https://alexatnet.com/article...
http://web.jobbole.com/84945/
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/82541.html
摘要:發布訂閱模式訂閱者把自己想訂閱的事件注冊到調度中心,當發布者發布該事件到調度中心,也就是該事件觸發時,由調度中心統一調度訂閱者注冊到調度中心的處理代碼。 發布-訂閱模式,看似陌生,其實不然。工作中經常會用到,例如 Node.js EventEmitter 中的 on 和 emit 方法;Vue 中的 $on 和 $emit 方法。他們都使用了發布-訂閱模式,讓開發變得更加高效方便。 一...
摘要:設計模式與開發實踐讀書筆記。發布訂閱模式又叫觀察者模式,它定義了對象之間的一種一對多的依賴關系。附設計模式之發布訂閱模式觀察者模式數據結構和算法系列棧隊列優先隊列循環隊列設計模式系列設計模式之策略模式 《JavaScript設計模式與開發實踐》讀書筆記。 發布-訂閱模式又叫觀察者模式,它定義了對象之間的一種一對多的依賴關系。當一個對象的狀態發生改變時,所有依賴它的對象都將得到通知。 例...
摘要:觀察者模式維護單一事件對應多個依賴該事件的對象關系發布訂閱維護多個事件主題及依賴各事件主題的對象之間的關系觀察者模式是目標對象直接觸發通知全部通知,觀察對象被迫接收通知。 觀察者模式(Observer) 觀察者模式:定義了對象間一種一對多的依賴關系,當目標對象 Subject 的狀態發生改變時,所有依賴它的對象 Observer 都會得到通知。 簡單點:女神有男朋友了,朋友圈曬個圖,甜...
摘要:生活中的觀察者模式就如我們在專賣店預定商品如蘋果手機,我們會向專賣店提交預定申請,然后店家受申請,正常這樣就完事了。中的觀察者模式在中觀察者模式的實現主要用事件模型。缺點使用全局的觀察者模式會明顯降低對象之間的聯系。 觀察者模式又叫做發布-訂閱模式。這是一種一對多的對象依賴關系,當被依賴的對象的狀態發生改變時,所有依賴于它的對象都將得到通知。 生活中的觀察者模式 就如我們在專賣店預定商...
閱讀 996·2023-04-25 14:45
閱讀 2773·2021-09-30 09:59
閱讀 3114·2021-09-22 15:48
閱讀 2425·2019-08-30 15:55
閱讀 3467·2019-08-30 15:44
閱讀 535·2019-08-29 14:07
閱讀 3412·2019-08-26 13:45
閱讀 536·2019-08-26 11:31