最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

理解javascript中的MVC模式

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

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ù)改變,并且實(shí)時(shí)的更新html頁面。當(dāng)然也包括一些事件的注冊或者ajax請求操作(發(fā)布事件),都是放在視圖層來完成。

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

下面我們來實(shí)現(xiàn)一個簡單的下拉框控件,我們可以對它進(jì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;
 
  // 增加一項(xiàng)
  this.itemAdd = new Event(this);
 
  // 刪除一項(xiàng)
  this.itemRemoved = new Event(this);
 
  this.selectedIndexChanged = new Event(this);
}
 
Mode.prototype = {
 
  constructor: 'Mode',
 
  // 獲取所有的項(xiàng)
  getItems: function(){
    return [].concat(this._elems);
  },
  // 增加一項(xiàng)
  addItem: function(elem) {
    this._elems.push(elem);
    this.itemAdd.notify({elem:elem});
  },
  // 刪除一項(xiàng)
  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)系,
 讓多個觀察者對象同時(shí)監(jiān)聽某一個主題對象,當(dāng)一個對象發(fā)生改變時(shí),所有依賴于它的對象都將得到通知。
*/
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ù)
 負(fù)責(zé)轉(zhuǎn)發(fā)請求,對請求進(jìn)行處理
*/
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();
});

代碼分析如下:

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

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

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

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

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

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

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

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

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

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

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

相關(guān)文章

  • JS實(shí)現(xiàn)簡潔、全兼容的拖動層實(shí)例

    JS實(shí)現(xiàn)簡潔、全兼容的拖動層實(shí)例

    這篇文章主要介紹了JS實(shí)現(xiàn)簡潔、全兼容的拖動層的方法,實(shí)例分析了javascript鼠標(biāo)事件及頁面元素的操作技巧,非常具有實(shí)用價(jià)值,需要的朋友可以參考下
    2015-05-05
  • BootstrapVue選項(xiàng)卡標(biāo)題增加關(guān)閉按鈕的方法

    BootstrapVue選項(xiàng)卡標(biāo)題增加關(guān)閉按鈕的方法

    這篇文章主要為大家詳細(xì)介紹了BootstrapVue選項(xiàng)卡標(biāo)題增加關(guān)閉按鈕的方法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-04-04
  • XMLHTTPRequest的屬性和方法簡介

    XMLHTTPRequest的屬性和方法簡介

    由于現(xiàn)在在公司負(fù)責(zé)制作標(biāo)準(zhǔn)的靜態(tài)頁面,為了增強(qiáng)客戶體驗(yàn),所以經(jīng)常要做些AJAX效果,也許你也和我一樣在,學(xué)習(xí)AJAX。
    2010-11-11
  • IE下JS讀取xml文件示例代碼

    IE下JS讀取xml文件示例代碼

    JS讀取xml文件具體步驟為:創(chuàng)建DOM對象、加載xml文件(僅適用于IE)附示例代碼,感興趣的朋友可以參考下,希望對大家有所幫助
    2013-08-08
  • js的es6常用新特性詳解

    js的es6常用新特性詳解

    ES6(ECMAScript 6,也稱為ES2015)是JavaScript的一個重要更新版本,引入了許多新的語言特性和改進(jìn),使得JavaScript變得更加現(xiàn)代化、易讀、易維護(hù)和更適合大型應(yīng)用程序的開發(fā),ES6的主要變化歸納為:語法糖、新機(jī)制、更好的語義、更多的內(nèi)置對象和方法
    2023-11-11
  • 微信小程序中顯示倒計(jì)時(shí)代碼實(shí)例

    微信小程序中顯示倒計(jì)時(shí)代碼實(shí)例

    這篇文章主要介紹了微信小程序中顯示倒計(jì)時(shí),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-05-05
  • 微信小程序開發(fā)探究

    微信小程序開發(fā)探究

    這篇文章主要介紹了微信小程序開發(fā)探究,非常具有實(shí)用價(jià)值,需要的朋友可以參考下。
    2016-12-12
  • 淺談layui 綁定form submit提交表單的注意事項(xiàng)

    淺談layui 綁定form submit提交表單的注意事項(xiàng)

    今天小編就為大家分享一篇淺談layui 綁定form submit提交表單的注意事項(xiàng),具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-10-10
  • 在JavaScript中使用揭示模式創(chuàng)建對象的示例

    在JavaScript中使用揭示模式創(chuàng)建對象的示例

    揭示模式是一種在JavaScript中創(chuàng)建對象的方法,通過返回一個包含公開屬性和方法的對象,可以控制哪些部分可以被外部訪問,從而實(shí)現(xiàn)更好的封裝和安全性,感興趣的朋友一起看看吧
    2024-12-12
  • 41個Web開發(fā)者必須收藏的JavaScript實(shí)用技巧

    41個Web開發(fā)者必須收藏的JavaScript實(shí)用技巧

    41個Web開發(fā)者必須收藏的JavaScript實(shí)用技巧,分享給大家,感興趣的小伙伴們可以參考一下
    2016-07-07

最新評論

金塔县| 镇江市| 赤峰市| 莱芜市| 湘潭市| 广丰县| 梨树县| 平原县| 东宁县| 中西区| 吴川市| 嘉荫县| 呼图壁县| 平遥县| 屏东市| 凤凰县| 荆州市| 闻喜县| 夹江县| 罗平县| 洛扎县| 隆安县| 泗洪县| 英超| 怀化市| 昌乐县| 运城市| 揭西县| 建瓯市| 吉林省| 磐石市| 钟祥市| 伽师县| 宁德市| 呼图壁县| 民县| 贡山| 潮安县| 兰坪| 方正县| 永丰县|