Maison > interface Web > js tutoriel > Comprendre brièvement le code source du modèle Model et la vue des connaissances Backbone.js_Basic

Comprendre brièvement le code source du modèle Model et la vue des connaissances Backbone.js_Basic

WBOY
Libérer: 2016-05-16 15:15:48
original
1054 Les gens l'ont consulté

Backbone.Modèle

Aujourd'hui, nous parlerons d'abord de M dans Backbone.js. Le modèle MVC est la partie centrale du backbone, qui contient les données pour le contenu d'affichage des pages, ainsi que diverses conversions, vérifications, calculs et contrôle des autorisations entourant les opérations de données. , interaction côté serveur et autres opérations, vous pouvez générer votre modèle via Backbone.Model.extend() Bien entendu, le modèle généré peut également être utilisé comme classe de base pour étendre davantage de modèles

.
 var People = Backbone.Model.extend({
     
 });

 var Man = People.extend({

 });

Copier après la connexion

Backbone.Model API

Backbone.Model fournit un grand nombre de méthodes pour implémenter les opérations de base d'un modèle. Bien entendu, la plus basique est le mécanisme événementiel basé sur Backbone.Events. Lorsque les attributs du modèle changent, le changement correspondant : L'événement attr sera Trigger, voici l'API fournie :

2016214171632823.png (207×574)

Il existe des méthodes pour effectuer des opérations côté serveur sur les données :

  • sync : encapsule Backbone.sync, la classe de base de xhr
  • fetch : utilisé pour récupérer les données du serveur
  • enregistrer : conserver les données sur le serveur
  • détruire : supprimer les données du serveur

Méthodes de manipulation des données dans le modèle :

  • obtenir : obtenir des données à partir des attributs
  • set : définir les données sur les attributs
  • escape : encodez les données à l'aide du caractère de soulignement _.escape
  • a : s'il existe des données correspondantes dans les attributs
  • non défini : supprimer les données des attributs
  • clear : Effacer les données d'attributs
  • changé : La valeur modifiée
  • par rapport à l'état précédent (set, unset a été exécuté)
  • toJSON : sérialiser les attributs dans un objet
  • analyser : lorsque l'élément de paramètre analyser est vrai, les données cibles seront analysées lors de l'initialisation/set/unset/fetch et d'autres opérations de données pour renvoyer l'objet analysé. Cette méthode est une méthode vide et doit être remplacée<🎜. >
  • hasChanged : indique s'il y a eu un changement par rapport à l'état précédent (set, unset a été exécuté)
  • changeAttributes : toutes les valeurs survenues par rapport à l'état précédent (set, unset a été exécuté)
  • précédent : état précédent (set, unset a été exécuté), la valeur correspondant à cet attribut
  • previousAttributes : Toutes les valeurs de l'état précédent de l'objet qui ont changé par rapport à l'état précédent (set, unset a été exécuté)
Méthodes de vérification des données dans le modèle :

    valider : utilisé pour vérifier les données dans le modèle, il doit être remplacé pour remplacer la méthode par défaut
  • validationError : renvoie la valeur renvoyée lorsque la dernière non-validité s'est produite
  • isValid : Appelez la méthode _validate
Certaines API clés seront expliquées ci-dessous :

Constructeur

  var Model = Backbone.Model = function(attributes, options) {
     var attrs = attributes || {};
     options || (options = {});
     this.cid = _.uniqueId('c');
     this.attributes = {};
     if (options.collection) this.collection = options.collection;
     if (options.parse) attrs = this.parse(attrs, options) || {};
     attrs = _.defaults({}, attrs, _.result(this, 'defaults'));
     this.set(attrs, options);
     this.changed = {};
     this.initialize.apply(this, arguments);
   };
Copier après la connexion
Le constructeur définit principalement les données et les options initialisées, puis génère un cid unique pour marquer le modèle. Si l'analyse dans les options est vraie, alors la valeur initialisée sera analysée via la méthode d'analyse et appellera la méthode set, toutes les valeurs initiales. sera stocké dans les attributs et la méthode d'initialisation initialize est appelée. L'initialisation du modèle est terminée.

ensemble

model.set(attributes, [options])

Copier après la connexion
La méthode set définira la valeur dans l'attribut. Si le client est défini sur true lors du réglage, l'événement change:attr correspondant sera déclenché. Enfin, l'événement change sera déclenché uniformément. la méthode est la suivante :

  set: function(key, val, options) {
     //......

      // key值可以是键值对,也可以是一个字符串,将赋值传入attrs属性中  
    if (typeof key === 'object') {
     attrs = key;
     options = val;
    } else {
     (attrs = {})[key] = val;
    }

   // ....

    //对设置的值进行校验 
      if (!this._validate(attrs, options)) return false;
    unset = options.unset; // unset为true时会删除设置的值,unset方法就是通过 set(key,val,{unset:true})去实现的
   
    //当对象正在被被设置的时候,不给 previousAttributes 赋值
    if (!changing) {
     this._previousAttributes = _.clone(this.attributes);
     this.changed = {};
    }
 
    current = this.attributes, prev = this._previousAttributes;
 
    //如果对Id进行了设置,则对对象的id属性也进行改变
    if (this.idAttribute in attrs) this.id = attrs[this.idAttribute];
 

    //进行 设置或者是删除操作
    for (attr in attrs) {
     val = attrs[attr];
     if (!_.isEqual(current[attr], val)) changes.push(attr);
     if (!_.isEqual(prev[attr], val)) {
      this.changed[attr] = val;//为model的changed进行设置
     } else {
      delete this.changed[attr];
     }
     unset &#63; delete current[attr] : current[attr] = val;//如果unset被设置成true了,则进行删除操作
    }
 
    //在silent不为false 的情况下,进行change:attr事件发送
    if (!silent) {
     if (changes.length) this._pending = options;
     for (var i = 0, l = changes.length; i < l; i++) {
      this.trigger('change:' + changes[i], this, current[changes[i]], options);
     }
    }
 

    //触发change事件
    if (changing) return this;
    if (!silent) {
     while (this._pending) {
      options = this._pending;
      this._pending = false;
      this.trigger('change', this, options);
     }
    }
    this._pending = false;
    this._changing = false;
    return this;
   
  }

Copier après la connexion
L'ensemble du processus de définition consiste à traiter la valeur entrante et à la transformer en une paire clé-valeur, puis à vérifier la valeur, à vérifier l'exactitude, puis à démarrer l'opération de configuration lors de la configuration, la valeur changera lors de la vérification. Si tel est le cas, ajoutez-le à un objet modifié, puis vérifiez la valeur de unset et effectuez les opérations d'ajout, de mise à jour et de suppression correspondantes. Ensuite, les événements change:attr et change sont déclenchés en séquence.

enregistrer

model.save([attributes], [options])

Copier après la connexion
La méthode de sauvegarde est utilisée pour conserver les données sur le client. Elle utilisera la création, la mise à jour ou le correctif en fonction des différentes données et configuration, et déclenchera l'événement de synchronisation. Ce qui suit fait partie du code :

  save: function(key, val, options) {     
    // ......
 

 
    //当设置了wait属性true的时候 , save方法先不执行set方法(不触发change事件),只执行validate
    if (attrs && !options.wait) {
     if (!this.set(attrs, options)) return false;
    } else {
     if (!this._validate(attrs, options)) return false;
    }

    //如果wait为true,设置this.attributes
    if (attrs && options.wait) {
     this.attributes = _.extend({}, attributes, attrs);
    }
 

    // .....
   
    var model = this;
    var success = options.success;
    options.success = function(resp) {
     // Ensure attributes are restored during synchronous saves.
     model.attributes = attributes;
     var serverAttrs = model.parse(resp, options);
     //如果wait为true , 那么会在请求返回之后才进行set操作
     if (options.wait) serverAttrs = _.extend(attrs || {}, serverAttrs);
     if (_.isObject(serverAttrs) && !model.set(serverAttrs, options)) {
      return false;
     }
     if (success) success(model, resp, options);
     //触发 sync 事件
     model.trigger('sync', model, resp, options);
    };

    //生成XHR onerror 回调函数
    wrapError(this, options);
    //选择方法
    method = this.isNew() &#63; 'create' : (options.patch &#63; 'patch' : 'update');
    if (method === 'patch') options.attrs = attrs;
    xhr = this.sync(method, this, options);
 
    // Restore attributes.
    if (attrs && options.wait) this.attributes = attributes;
    //返回xhr对象
    return xhr;
  }

Copier après la connexion


save 中最需要注意的就是 wait 的设置,当wait为真的时候,save返回会在xhr返回之后再执行set操作,而不是在xhr之前就进行set操作,因此change事件的触发时机也就不同了。

之前说过整个Backbone都是通过事件串联起来的,所以对于事件触发时机的了解和把握是非常重要的,不然会在开发过程中导致一些奇怪的问题出现。

Backbone.View
前面已经对backbone中的Event、Model、Collection代码进行了分析,现在我们来看下MVC中的V部分,也就是Backbone.View,View在Backbone中主要用于沟通页面中的DOM和Backbone.Model/Collection,页面的逻辑操作,DOM事件的绑定等,View部分的代码非常简答,加上注释只有110左右。 View部分有一下API:

2016214171843674.png (197×245)

方法不多,下面对部分API进行介绍:

构造方法

  var viewOptions = ['model', 'collection', 'el', 'id', 'attributes', 'className', 'tagName', 'events'];
 var View = Backbone.View = function(options) {
   this.cid = _.uniqueId('view');
   options || (options = {});
   _.extend(this, _.pick(options, viewOptions));
   this._ensureElement();
   this.initialize.apply(this, arguments);
   this.delegateEvents();
 };
Copier après la connexion

构造方法中为View生成了一个唯一的cid,以'view'开头,然后进行对目标属性viewOptions进行合并,接着调用_ensureElement判断el的情况,接着调用delegateEvents进行方法绑定,初始化完成 。

delegateEvents

view.setElement(element)

   setElement: function(element, delegate) {
    if (this.$el) this.undelegateEvents();//如果已经存在this.$el,进行事件解绑

    //对$el进行赋值,本质是一个jquery或者是 Lo-Dash and Zepto 对象
    this.$el = element instanceof Backbone.$ &#63; element : Backbone.$(element);
    //把dom element 赋值给el
    this.el = this.$el[0];

     //如果没有显式传值,则进行事件绑定
    if (delegate !== false) this.delegateEvents();
    return this;
   }

Copier après la connexion

setElement方法用于设置View对应的element , 这个方法在new的时候会被调用, 如果想要在使用过程中改变View的dom元素指向,可调用这个方法进行重新设置

_ensureElement

  _ensureElement: function() {
     //如果已经对el进行设置,直接调用setElement方法
    if (!this.el) {//如果没有设置,生成一个元素对象,再调用setElement方法
     var attrs = _.extend({}, _.result(this, 'attributes'));
     if (this.id) attrs.id = _.result(this, 'id');
     if (this.className) attrs['class'] = _.result(this, 'className');
     var $el = Backbone.$('<' + _.result(this, 'tagName') + '>').attr(attrs);
     this.setElement($el, false);
    } else {
     this.setElement(_.result(this, 'el'), false);
    }
  }
Copier après la connexion

_ensureElement这个方法是内部方法,在构造函数中使用,用于判断指定的el在页面中存不存在,如果存在则对$el进行赋值,如果不存在,则生成一个$el,但是要注意这个对象是没有落地到dom树中的 。

delegateEvents

delegateEvents([events])

    // *{"event selector": "callback"}*
   //
   //   {
   //    'mousedown .title': 'edit',
   //    'click .button':   'save',
   //    'click .open':    function(e) { ... }
   //   }

   delegateEvents: function(events) {
      //如果不存在events,则直接返回
      if (!(events || (events = _.result(this, 'events')))) return this;
   
      //先解除所有的事件绑定
      this.undelegateEvents();
   
      //处理每个事件
      for (var key in events) {
       var method = events[key];
       //解析回调函数
       if (!_.isFunction(method)) method = this[events[key]];
       if (!method) continue;
   
       //对选择器进行分析
       var match = key.match(delegateEventSplitter);
       var eventName = match[1], selector = match[2];
       method = _.bind(method, this);
   
       //绑定的事件名都是以 eventName + '.delegateEvents' + cid 组成,
       //这么做能够在undelegateEvents的时候选择到这个View的所有事件
       eventName += '.delegateEvents' + this.cid;
       if (selector === '') {
        this.$el.on(eventName, method);
       } else {
        this.$el.on(eventName, selector, method);
       }
      }
      return this;
   }

Copier après la connexion

在View中你可以使用一个 key:value 集合指定对应的事件,在初始化的时候构造函数会调用delegateEvents进行绑定,需要注意的是所有在key中指定的元素的父元素都必须是$el,也就是说元素必须是$el的子节点,否则绑定失败。

View和其他backbone模块一个区别就是没有自己的内建自定义事件,当然他也组合了Events模块,但是所有的事件都需要自己进行建立。View主要是一个MVC模型的承载,其实真正的功能不多,其实从模型层面上看V在前端开发中是最接近业务逻辑的,所以在View中大部分的逻辑都是开发者自己去扩展的。

Étiquettes associées:
source:php.cn
Déclaration de ce site Web
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
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal