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

理解javascript中的MVC模式

 更新時間:2016年01月28日 15:19:34   投稿:lijiao  
這篇文章主要為大家介紹了javascript中的MVC模式,MVC是一種軟件架構(gòu)模式,一般把軟件模式分為三部分,本文就針對MVC模式的三部分進行講解,感興趣的小伙伴們可以參考一下

MVC模式是軟件工程中一種軟件架構(gòu)模式,一般把軟件模式分為三部分,模型(Model)+視圖(View)+控制器(Controller);

模型:模型用于封裝與應(yīng)用程序的業(yè)務(wù)邏輯相關(guān)的數(shù)據(jù)以及對數(shù)據(jù)處理的方法。模型有對數(shù)據(jù)直接訪問的權(quán)利。模型不依賴 “視圖” 和 “控制器”, 也就是說 模型它不關(guān)心頁面如何顯示及如何被操作.

視圖:視圖層最主要的是監(jiān)聽模型層上的數(shù)據(jù)改變,并且實時的更新html頁面。當然也包括一些事件的注冊或者ajax請求操作(發(fā)布事件),都是放在視圖層來完成。

控制器:控制器接收用戶的操作,最主要是訂閱視圖層的事件,然后調(diào)用模型或視圖去完成用戶的操作;比如:當頁面上觸發(fā)一個事件,控制器不輸出任何東西及對頁面做任何處理; 它只是接收請求并決定調(diào)用模型中的那個方法去處理請求, 然后再確定調(diào)用那個視圖中的方法來顯示返回的數(shù)據(jù)。

下面我們來實現(xiàn)一個簡單的下拉框控件,我們可以對它進行增刪操作;如下圖所示:

代碼如下:

/*
 模型用于封裝與應(yīng)用程序的業(yè)務(wù)邏輯相關(guān)的數(shù)據(jù)以及對數(shù)據(jù)處理的方法。模型有對數(shù)據(jù)直接訪問的權(quán)利。
 模型不依賴 "視圖" 和 "控制器", 也就是說 模型它不關(guān)心頁面如何顯示及如何被操作.
*/
function Mode(elems) {
  // 所有元素
  this._elems = elems;
 
  // 被選中元素的索引
  this._selectedIndex = -1;
 
  // 增加一項
  this.itemAdd = new Event(this);
 
  // 刪除一項
  this.itemRemoved = new Event(this);
 
  this.selectedIndexChanged = new Event(this);
}
 
Mode.prototype = {
 
  constructor: 'Mode',
 
  // 獲取所有的項
  getItems: function(){
    return [].concat(this._elems);
  },
  // 增加一項
  addItem: function(elem) {
    this._elems.push(elem);
    this.itemAdd.notify({elem:elem});
  },
  // 刪除一項
  removeItem: function(index) {
    var item = this._elems[index];
    this._elems.splice(index,1);
    this.itemRemoved.notify({elem:item});
 
    if(index === this._selectedIndex) {
      this.setSelectedIndex(-1);
    }
  },
  getSelectedIndex: function(){
    return this._selectedIndex;
  },
  setSelectedIndex: function(index){
    var previousIndex = this._selectedIndex;
    this._selectedIndex = index;
    this.selectedIndexChanged.notify({previous : previousIndex});
  }
};
/*
 下面是觀察者模式類,它又叫發(fā)布---訂閱模式;它定義了對象間的一種一對多的關(guān)系,
 讓多個觀察者對象同時監(jiān)聽某一個主題對象,當一個對象發(fā)生改變時,所有依賴于它的對象都將得到通知。
*/
function Event(observer) {
  this._observer = observer;
  this._listeners = [];
}
Event.prototype = {
  constaructor: 'Event',
  attach : function(listeners) {
    this._listeners.push(listeners);
  },
  notify: function(objs){
    for(var i = 0,ilen = this._listeners.length; i ) {
      this._listeners[i](this._observer,objs);
    }
  }
};
 
/*
 * 視圖顯示模型數(shù)據(jù),并觸發(fā)UI事件。
 */
function View(model,elements){
  this._model = model;
  this._elements = elements;
 
  this.listModified = new Event(this);
  this.addButtonClicked = new Event(this);
  this.delButtonClicked = new Event(this);
  var that = this;
 
  // 綁定模型監(jiān)聽器
  this._model.itemAdd.attach(function(){
    that.rebuildList();
  });
  this._model.itemRemoved.attach(function(){
    that.rebuildList();
  });
 
  // 將監(jiān)聽器綁定到HTML控件上
  this._elements.list.change(function(e){
    that.listModified.notify({index: e.target.selectedIndex});
  });
  // 添加按鈕綁定事件
  this._elements.addButton.click(function(e){
    that.addButtonClicked.notify();
  });
  // 刪除按鈕綁定事件
  this._elements.delButton.click(function(e){
    that.delButtonClicked.notify();
  });
}
View.prototype = {
  constructor: 'View',
  show: function(){
    this.rebuildList();
  },
  rebuildList: function(){
    var list = this._elements.list,
      items,
      key;
    list.html("");
    items = this._model.getItems();
    for(key in items) {
      if(items.hasOwnProperty(key)) {
        list.append('' +items[key]+ '');
      }
    }
    this._model.setSelectedIndex(-1);
  }
};
/*
 控制器響應(yīng)用戶操作,調(diào)用模型上的變化函數(shù)
 負責(zé)轉(zhuǎn)發(fā)請求,對請求進行處理
*/
function Controller(model,view) {
  this._model = model;
  this._view = view;
  var that = this;
 
  this._view.listModified.attach(function(sender,args){
    that.updateSelected(args.index);
  });
  this._view.addButtonClicked.attach(function(){
    that.addItem();
  });
  this._view.delButtonClicked.attach(function(){
    that.delItem();
  });
}
Controller.prototype = {
  constructor: 'Controller',
 
  addItem: function(){
    var item = window.prompt('Add item:', '');
    if (item) {
      this._model.addItem(item);
    }
  },
 
  delItem: function(){
    var index = this._model.getSelectedIndex();
    if(index !== -1) {
      this._model.removeItem(index);
    }
  },
 
  updateSelected: function(index){
    this._model.setSelectedIndex(index);
  }
};

HTML代碼如下:

<select id="list" size="10" style="width: 10rem">select>br/>
<button id="plusBtn"> + button>
<button id="minusBtn"> - button>

頁面初始化代碼如下:

$(function () {
  var model = new Mode(['PHP', 'JavaScript']),
   view = new View(model, {
    'list' : $('#list'), 
    'addButton' : $('#plusBtn'), 
    'delButton' : $('#minusBtn')
    }),
    controller = new Controller(model, view);    
    view.show();
});

代碼分析如下:

  先分析下我們是要實現(xiàn)什么樣的功能,基本功能有:

一個下拉框,通過用戶輸入的操作來實現(xiàn)用戶增加一項及用戶選中一項后刪除一項的功能;
當然也添加了用戶切換到那一項的事件;

比如我們現(xiàn)在來增加一條數(shù)據(jù)的時候,在視圖層上添加監(jiān)聽事件,如下代碼:

// 添加按鈕綁定事件
this._elements.addButton.click(function(e){
  that.addButtonClicked.notify();
});

然后調(diào)用觀察者類Event中的方法notify(發(fā)布一個事件) that.addButtonClicked.notify();大家都知道,觀察者模式又叫發(fā)布-訂閱模式,讓多個觀察者對象同時監(jiān)聽某一個主題對象,當某一個主題對象發(fā)生改變的時候,所有依賴它的對象都會得到通知;
因此在控制層(Controller)我們可以使用如下代碼對發(fā)布者進行監(jiān)聽操作:

this._view.addButtonClicked.attach(function(){
  that.addItem();
});

之后調(diào)用自身的方法addItem();代碼如下:

addItem: function(){
  var item = window.prompt('Add item:', '');
  if (item) {
    this._model.addItem(item);
  }
}

調(diào)用模型層(model)的方法addItem();把一條數(shù)據(jù)插入到select框里面去;model(模型層)的addItem()方法代碼如下:

// 增加一項
addItem: function(elem) {
  this._elems.push(elem);
  this.itemAdd.notify({elem:elem});
},

如上代碼 增加一項后,通過 this.itemAdd 發(fā)布一個消息,然后在視圖層(View)上通過如下代碼來監(jiān)聽這個消息;代碼如下:

// 綁定模型監(jiān)聽器
this._model.itemAdd.attach(function(){
   that.rebuildList();
});

最后監(jiān)聽到模型上(Model)的數(shù)據(jù)發(fā)生改變后,及時調(diào)用自身的方法rebuildList()去更新頁面上的數(shù)據(jù);

模型層(Model)最主要做業(yè)務(wù)數(shù)據(jù)封裝操作。視圖層(View)主要發(fā)布事件操作及監(jiān)聽模型層上的數(shù)據(jù),如果模型層上有數(shù)據(jù)改變的時候,及時更新頁面操作,最后顯示給頁面上來,控制層(Controller)主要監(jiān)聽視圖層(View)的事件,調(diào)用模型層(Model)的方法來更新模型上的數(shù)據(jù),模型層數(shù)據(jù)更新后,會發(fā)布一條消息出去,最后視圖層(View)通過監(jiān)聽模型層(Model)的數(shù)據(jù)變化,來更新頁面的顯示; 如上是MVC的基本流程。
MVC的優(yōu)點:
        1. 耦合性低:視圖層和業(yè)務(wù)層分離了,如果頁面上顯示改變的話,直接在視圖層更改即可,不用動模型層和控制層上的代碼;也就是視圖層 與 模型層和控制層
已經(jīng)分離了;所以很容易改變應(yīng)用層的數(shù)據(jù)層和業(yè)務(wù)規(guī)則。
        2. 可維護性:分離視圖層和業(yè)務(wù)邏輯層也使得WEB應(yīng)用更易于維護和修改。
MVC的缺點:
        個人覺得適合于大型項目,對于中小型項目并不適合,因為要實現(xiàn)一個簡單的增刪改操作,只需要一點點JS代碼,但是MVC模式代碼量明顯增加了。
對于學(xué)習(xí)成本也就提高了,當然如果使用一些封裝好的MVC庫或者框架就好了。

以上就是關(guān)于javascript中的MVC模式實現(xiàn)方法,優(yōu)缺點的詳細分析,希望對大家的學(xué)習(xí)有所幫助。

相關(guān)文章

  • package.json中homepage屬性的作用詳解

    package.json中homepage屬性的作用詳解

    這篇文章主要介紹了package.json中homepage屬性的作用詳解,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-03-03
  • 一個js封裝的不錯的選項卡效果代碼

    一個js封裝的不錯的選項卡效果代碼

    在論壇里經(jīng)??吹饺藛栠x項卡或者類似選項卡的切換效果 這里封裝了個js,希望對大家有用 所有代碼都在下面了 如果有錯誤或者建議,可以回貼告訴我,謝謝
    2008-02-02
  • js實現(xiàn)遍歷含有input的table實例

    js實現(xiàn)遍歷含有input的table實例

    這篇文章主要介紹了js實現(xiàn)遍歷含有input的table方法,結(jié)合實例形式分析了jsp讀取數(shù)據(jù)庫動態(tài)生成table及JavaScript遍歷table的相關(guān)技巧,需要的朋友可以參考下
    2015-12-12
  • 微信小程序?qū)崿F(xiàn)文字從右向左無限滾動

    微信小程序?qū)崿F(xiàn)文字從右向左無限滾動

    這篇文章主要為大家詳細介紹了微信小程序?qū)崿F(xiàn)文字從右向左無限滾動,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-12-12
  • javascript日期對象格式化為字符串的實現(xiàn)方法

    javascript日期對象格式化為字符串的實現(xiàn)方法

    本篇文章主要是對javascript日期對象格式化為字符串的實現(xiàn)方法進行了詳細的介紹,需要的朋友可以過來參考下,希望對大家有所幫助
    2014-01-01
  • JS實現(xiàn)拖拽進度條改變元素透明度

    JS實現(xiàn)拖拽進度條改變元素透明度

    這篇文章主要為大家詳細介紹了JS實現(xiàn)拖拽進度條改變元素透明度,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-10-10
  • JS基于構(gòu)造函數(shù)實現(xiàn)的菜單滑動顯隱效果【測試可用】

    JS基于構(gòu)造函數(shù)實現(xiàn)的菜單滑動顯隱效果【測試可用】

    這篇文章主要介紹了JS基于構(gòu)造函數(shù)實現(xiàn)的菜單滑動顯隱效果,可實現(xiàn)基本的菜單折疊與展開功能,涉及javascript響應(yīng)鼠標事件動態(tài)操作頁面元素的相關(guān)技巧,需要的朋友可以參考下
    2016-06-06
  • JavaScript實現(xiàn)雪花飄落效果

    JavaScript實現(xiàn)雪花飄落效果

    這篇文章主要為大家詳細介紹了JavaScript實現(xiàn)雪花飄落效果,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-12-12
  • 動態(tài)加載js、css的實例代碼

    動態(tài)加載js、css的實例代碼

    這篇文章主要介紹了動態(tài)加載js、css的實例代碼的相關(guān)資料,非常不錯具有參考借鑒價值,感興趣的朋友一起看看吧
    2016-05-05
  • JS定時器不可靠的原因及解決方案

    JS定時器不可靠的原因及解決方案

    JavaScript中所有的任務(wù)分為同步任務(wù)與異步任務(wù),同步任務(wù),顧名思義就是立即執(zhí)行的任務(wù),它一般是直接進入到主線程中執(zhí)行,這篇文章主要介紹了JS定時器不可靠的原因及解決方案,需要的朋友可以參考下
    2022-01-01

最新評論