Maison  >  Article  >  interface Web  >  Comprendre le modèle MVC dans les astuces javascript_javascript

Comprendre le modèle MVC dans les astuces javascript_javascript

WBOY
WBOYoriginal
2016-05-16 15:17:031263parcourir

Le modèle MVC est un modèle d'architecture logicielle en génie logiciel. Le modèle logiciel est généralement divisé en trois parties : modèle, vue et contrôleur ;

Modèle : Le modèle est utilisé pour encapsuler les données liées à la logique métier de l'application et aux méthodes de traitement des données. Les modèles ont un accès direct aux données. Le modèle ne s'appuie pas sur la « vue » et le « contrôleur », ce qui signifie que le modèle ne se soucie pas de la façon dont la page est affichée et de la façon dont elle est exploitée.

Vue : la chose la plus importante de la couche de vue est de surveiller les modifications des données sur la couche modèle et de mettre à jour la page html en temps réel. Bien entendu, cela inclut également certaines opérations d’enregistrement d’événements ou de requêtes ajax (événements de publication), qui sont toutes effectuées dans la couche de visualisation.

Contrôleur : Le contrôleur reçoit l'opération de l'utilisateur, le plus important est de s'abonner aux événements de la couche vue, puis d'appeler le modèle ou la vue pour terminer l'opération de l'utilisateur par exemple : lorsqu'un événement est déclenché sur le ; page, le contrôleur ne produit rien et répond. La page n'effectue aucun traitement ; elle reçoit simplement la requête et décide quelle méthode du modèle appeler pour gérer la requête, puis détermine quelle méthode dans la vue appeler pour afficher les données renvoyées. .

Implémentons un simple contrôle de liste déroulante, que nous pouvons ajouter et supprimer comme indiqué dans la figure ci-dessous :

Le code est le suivant :

/*
 模型用于封装与应用程序的业务逻辑相关的数据以及对数据处理的方法。模型有对数据直接访问的权利。
 模型不依赖 "视图" 和 "控制器", 也就是说 模型它不关心页面如何显示及如何被操作.
*/
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});
  }
};
/*
 下面是观察者模式类,它又叫发布---订阅模式;它定义了对象间的一种一对多的关系,
 让多个观察者对象同时监听某一个主题对象,当一个对象发生改变时,所有依赖于它的对象都将得到通知。
*/
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);
    }
  }
};
 
/*
 * 视图显示模型数据,并触发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;
 
  // 绑定模型监听器
  this._model.itemAdd.attach(function(){
    that.rebuildList();
  });
  this._model.itemRemoved.attach(function(){
    that.rebuildList();
  });
 
  // 将监听器绑定到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);
  }
};
/*
 控制器响应用户操作,调用模型上的变化函数
 负责转发请求,对请求进行处理
*/
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);
  }
};

Le code HTML est le suivant :

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

Le code d'initialisation de la page est le suivant :

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

L'analyse du code est la suivante :

Analysons d'abord quel type de fonctions nous voulons réaliser Les fonctions de base sont :

Une zone déroulante qui permet à l'utilisateur d'ajouter un élément et de supprimer un élément après l'avoir sélectionné via des opérations de saisie utilisateur ;
Bien sûr, l'événement permettant à l'utilisateur de basculer vers cet élément est également ajouté

 ;

Par exemple, lorsque nous ajoutons une donnée maintenant, ajoutez un événement d'écoute sur la couche de vue, comme indiqué dans le code suivant :

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

Appelez ensuite la méthode notify dans la classe observateur Event (publier un événement) that.addButtonClicked.notify(); Comme nous le savons tous, le mode observateur est également appelé mode publication-abonnement, permettant à plusieurs objets observateurs de surveiller un certain événement en même temps. Objet thème, lorsqu'un objet thème change, tous les objets qui en dépendent seront notifiés
; Par conséquent, dans la couche de contrôle (Controller) nous pouvons utiliser le code suivant pour surveiller l'éditeur :

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

Appelez ensuite sa propre méthode addItem(); le code est le suivant :

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

Appelez la méthode addItem() de la couche modèle (model) ; insérez une donnée dans la boîte de sélection ; le code de la méthode addItem() du modèle (model layer) est le suivant :

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

Le code ci-dessus ajoute un élément, publie un message via this.itemAdd, puis surveille le message via le code suivant sur la couche de vue (View) :

// 绑定模型监听器
this._model.itemAdd.attach(function(){
   that.rebuildList();
});

Après avoir finalement surveillé les données sur le modèle (Model), il appelle rapidement sa propre méthode reconstructionList() pour mettre à jour les données sur la page

;

La couche modèle (Model) est principalement responsable des opérations d'encapsulation des données métiers. La couche de vue (View) publie principalement les opérations d'événement et surveille les données sur la couche modèle. Si les données sur la couche modèle changent, elle mettra à jour l'opération de page dans le temps et l'affichera finalement sur la page principalement. surveille la couche de vue (événement View), appelez la méthode de la couche de modèle (Modèle) pour mettre à jour les données sur le modèle. Une fois les données de la couche de modèle mises à jour, un message sera publié. met à jour la page en surveillant les modifications des données de la couche modèle (Modèle Affichage) Ce qui précède est le processus de base de MVC.
Avantages du MVC :
  1. Faible couplage : La couche de vue et la couche métier sont séparées Si l'affichage sur la page change, il peut être modifié directement dans la couche de vue sans toucher au modèle. calque et contrôle Le code sur le calque ; c'est-à-dire le calque de vue, le calque de modèle et le calque de contrôle
Déjà séparé ; il est donc facile de modifier la couche de données et les règles métier de la couche d'application.
​​   2. Maintenabilité : La séparation de la couche de vue et de la couche de logique métier facilite également la maintenance et la modification des applications WEB.
Inconvénients du MVC :
Personnellement, je pense qu'il convient aux grands projets, et qu'il ne convient pas aux projets de petite et moyenne taille, car pour réaliser une simple opération d'ajout, de suppression et de modification, seul un peu de code JS est requis, mais la quantité de code en mode MVC a considérablement augmenté.
Le coût de l'apprentissage augmentera également. Bien sûr, il serait préférable que vous utilisiez des bibliothèques ou des frameworks MVC encapsulés.

Ce qui précède est une analyse détaillée de la méthode d'implémentation du modèle MVC en JavaScript, ses avantages et ses inconvénients, j'espère que cela sera utile à l'apprentissage de chacun.

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn