フロントエンドコンポーネント開発方式(二)

11129 ワード

まずclassを見て、継承のコードの実現に似ています
var Class = (function() {
  var _mix = function(r, s) {
    for (var p in s) {
      if (s.hasOwnProperty(p)) {
        r[p] = s[p]
      }
    }
  }

  var _extend = function() {

    //   , init
    this.initPrototype = true
    var prototype = new this()
    this.initPrototype = false

    var items = Array.prototype.slice.call(arguments) || []
    var item

    // , {}  Function
    while (item = items.shift()) {
      _mix(prototype, item.prototype || item)
    }


    //
    function SubClass() {
      if (!SubClass.initPrototype && this.init)
        this.init.apply(this, arguments)// init 
    }

    //
    SubClass.prototype = prototype

    //  constructor 
    SubClass.prototype.constructor = SubClass

    //  extend 
    SubClass.extend = _extend

    return SubClass
  }
  // 
  var Class = function() {}
  // extend 
  Class.extend = _extend

  return Class
})()

使用方法は以下の通りです.
// , Animal, 。 Animal 。
// {}, Function
var Animal = Class.extend({
  init:function(opts){
    this.msg = opts.msg
    this.type = "animal"
  },
  say:function(){
    alert(this.msg+":i am a "+this.type)
  }
})


// Animal, 
var Dog = Animal.extend({
  init:function(opts){
    // super , 
    Animal.prototype.init.call(this,opts)
    // type 
    this.type = "dog"
  }
})

//new Animal({msg:'hello'}).say()

new Dog({msg:'hi'}).say()

次に、特定のコンポーネントがこの方法を適用します.
var TextCount = Class.extend({
    init:function(config){
        this.input = $(config.id);
        this._bind();
        this.render();
    },
    render:function(){
        var num = this._getNum();
        if($("#J_input_count").length==0){
            this.input.after('<span id="J_input_count"></span');
        };
        $("#J_input_count").html(num+' ');
    },
    _getNum:function(){
        return this.input.val().length;
    },
    _bind:function(){
        var self = this;
        self.input.on('keyup',function(){
            self.render();
        })
    }
})
$(function(){
    new TextCount({id:'#J_input'});
})
// 
var
Base = Class.extend({ init:function(config){ this.__config = config; this.bind(); this.render(); }, get:function(key){ return this.__config[key]; }, set:function(key,value){ this.__config[key] = value; }, bind:function(){ }, render:function(){ }, destroy:function(){ } })

 
var TextCount = Base.extend({
    _getNum :function(){
        return this.get('input').val().length;
    },
    bind:function(){
        var self = this;
        self.get('input').on('keyup',function(){
            self.render();
        });
    },
    render:function(){
        var num = this._getNum();
        if($("#J_input_count").length==0){
            this.get('input').after('<span id="J_input_count"></span');
        }
        $("J_input_count").html(num+' ');
    },
})
$(function(){
    new TextCount({
        input:$("#J_input");
    })
})