takahashiakira
10/2/2015 - 2:17 AM

BaseView Class v2.0.0

BaseView Class v2.0.0

BaseView Class

全ての継承元となるView。templateが存在すればelにtemplateを自動でrenderする。modelを渡した際はmodelをtemplateにレンダリング、collectionを渡した際はtemplateにイテレートする。両方渡した際はcollectionが優先される。任意でparentViewを設定も可。init()、setOptions()、render()、remove()、setEl()は継承で上書きしないように注意。

Class (Prototype)

var _ = require('underscore');

/**
 * BaseView Class Description v2.0.0
 * @fileoverview 全ての継承元となるView。templateが存在すればelにtemplateを自動でrenderする。modelを渡した際はmodelをtemplateにレンダリング、collectionを渡した際はtemplateにイテレートする。両方渡した際はcollectionが優先される。任意でparentViewを設定も可。init()、setOptions()、render()、remove()、setEl()は継承で上書きしないように注意。
 *    対応ブラウザはモダンブラウザ(IE8以上)
 */
 var BaseView = (function () {
  var constructor = function () {
    this.$el = {};
    this.model = {};
    this.collection = [];
    this.status = {};
    this.template = null;
    this.parentView = {};
    return this;
  };
  var proto = constructor.prototype;
  /**
   * Entry point
   * @param {Object} args
   *    @param {Object} el - 全ての要素を含んだラッパーのDOM要素。
   *    @param {Object} model - modelを紐付ける
   *    @param {Array} collection - collectionを紐付ける
   *    @param {Function} template - templateを渡せる
   *    @param {Array} parentView - 親Viewを持たせて連携させたい場合はここで設定。配列で複数のparentViewを渡せる
   */
  proto.init = function (args) {
    var that = this;
    this.deferredOptions = $.Deferred();
    if(this.el){
      this.$el = $(this.el);
    }
    if(args){
      if(args.el){
        this.$el = $(args.el);
      }
      this.setOptions(args);
    }else{
      this.deferredOptions.resolve();
    }
    this.deferredOptions.promise().then(function() {
      that.deferredRender = $.Deferred();
      that.render();
      return that.deferredRender.promise();
    }).then(function() {
      that.deferredSetEl = $.Deferred();
      that.setEl();
      return that.deferredSetEl.promise();
    }).then(function() {
      that.setEvents();
      that.setCustomEvents();
      that.setFn();
      that.resetModel();
      that.resetStatus();
    });
    return this;
  };
  proto.setOptions = function (args) {
    if(args.collection){
      this.collection = args.collection;
    }else if(args.model){
      this.model = new Object(args.model);
    }
    if(args.template){
      this.template = args.template;
    }
    this.parentView = args.parentView;
    this.deferredOptions.resolve();
    return this;
  };
  proto.render = function () {
    var that = this;
    if(this.template){
      this.remove();
      if(this.collection.length > 0){
        var tmpEls = [];
        _.each(that.collection, function(model) {
          var el = that.template({data: model});
          tmpEls.push(el);
        });
        this.$el.append(tmpEls.join(''));
      }else if(this.model){
        this.$el.append(this.template({data: this.model}));
      }else{
        this.$el.append(this.template());
      }
    }
    this.deferredRender.resolve();
    return this;
  };
  proto.remove = function () {
    // viewの削除
    this.$el.children().remove();
    return this;
  };
  proto.setEl = function () {
    // DOM要素のひもづけ
    this.deferredSetEl.resolve();
    return this;
  };
  proto.setEvents = function () {
    // イベントハンドリング
    return this;
  };
  proto.resetEvents = function () {
    return this;
  };
  proto.setCustomEvents = function () {
    // オブザーバパターンのカスタムイベントハンドリング
    return this;
  };
  proto.setFn = function () {
    // 関数の評価
    return this;
  };
  proto.resetModel = function () {
    // modelの初期化
    return this;
  };
  proto.resetStatus = function () {
    // 状態をリセット
    return this;
  };
  proto.destroy = function () {
    this.resetEvents();
    this.remove();
    return this;
  };
  return constructor;
})();

Usage

HTML

<div id="view"></div>

JS

var baseView = new BaseView();
baseView.init({
  el: '#view'
});

// 削除する場合は以下のメソッド
// baseView.destroy();