javascript設計模式(張容銘) 第14章 超值午飯-組合模式 學習筆記

JS 組合模式更經常使用於建立表單上,好比註冊頁面可能有不一樣的表單提交模塊。對於這些需求咱們只須要有基本的個體,而後經過必定的組合便可實現,好比下面這個頁面樣式(如圖14-2所示),咱們來用組合模式實現。html

做者給的提示,首先建立基類 Base, 而後三個組合類 FormItem、FieldsetItem、Group,以及成員類InputItem、LabelItem、SpanItem、TextareaItem,建立完以後像下面這樣拼出你的註冊頁面吧。app

var form = new FormItem('FormItem', document.body);

form.add(
  new FieldsetItem('account', '帳號').add(
    new Group().add(
      new LabelItem('user_name', '用戶名:')
    ).add(
      new InputItem('user_name')
    ).add(
      new SpanItem('4到6位數字或字母')
    )
  ).add(
    new Group().add(
      new LabelItem('user_password', '密 碼:')
    ).add(
      new InputItem('user_password')
    ).add(
      new SpanItem('6到12位數字或者密碼')
    )
  )
).add(
  new FieldsetItem('info', '信息').add(
    new Group().add(
      new LabelItem('pet_name', '暱稱:')
    ).add(
      new InputItem('user_pet_name')
    )
  ).add(
    new Group().add(
      new LabelItem('user_status', '狀態:')
    ).add(
      new InputItem('user_status')
    )
  )
)

 

下面咱們來挨個建立個體類。函數

// 原型式繼承
function inheritObject(o) {
  // 聲明一個過渡函數對象
  function F() {}
  // 過渡函數的原型繼承父對象
  F.prototype = o;
  // 返回過渡對象的一個實例,該實例的原型繼承了父對象
  return new F();
}

/**
 * 寄生式繼承 繼承原型
 * 傳遞參數 subClass 子類
 * 傳遞參數 superClass 父類
**/
function inheritPrototype(subClass, superClass) {
  // 複製一份父類的原型副本保存在變量中
  var p = inheritObject(superClass.prototype);
  // 修正由於重寫子類原型致使子類的constructor屬性被修改
  p.constructor = subClass;
  // 設置子類的原型
  subClass.prototype = p;
}

 

首先建立總的虛擬父類 Form測試

var Form = function() {
  // 子組件容器
  this.children = [];
  // 當前組件元素
  this.element = null;
}

Form.prototype = {
  init: function() {
    throw new Error('請重寫你的方法');
  },
  add: function() {
    throw new Error('請重寫你的方法');
  },
  getElement: function() {
    throw new Error('請重寫你的方法');
  },
}

 

FormItem 容器構造函數this

var FormItem = function(id, parent) {
  // 構造函數繼承父類
  Form.call(this);
  // 模塊id
  this.id = id;
  // 模塊的父容器
  this.parent = parent;
  // 構建方法
  this.init();
}

// 寄生式繼承父類原型方法
inheritPrototype(FormItem, Form);

// 構建方法
FormItem.prototype.init = function() {
  this.element = document.createElement('form');
  this.element.id = this.id;
  this.element.className = 'new-form';
}

FormItem.prototype.add = function(child) {
    // 在子元素容器中插入子元素
    this.children.push(child);
    // 插入當前組件元素樹中
    this.element.appendChild(child.getElement());
    return this;
}

// 獲取當前元素方法
FormItem.prototype.getElement = function() {
  return this.element;
}

// 顯示方法
FormItem.prototype.show = function() {
  this.parent.appendChild(this.element);
}

 

FieldsetItem 容器構造函數spa

var FieldsetItem = function(id, fieldName) {
  Form.call(this);
  this.fieldName = fieldName || '';
  this.init();
}

inheritPrototype(FieldsetItem, Form);

FieldsetItem.prototype.init = function() {
  this.element = document.createElement('fieldset');
  var legend = document.createElement('legend');
  legend.innerHTML = this.fieldName;
  this.element.appendChild(legend);
}

FieldsetItem.prototype.add = function(child) {
  this.children.push(child);
  this.element.appendChild(child.getElement());
  return this;
}

FieldsetItem.prototype.getElement = function() {
  return this.element;
}

 Group 容器構造函數prototype

var Group = function() {
  Form.call(this);
  this.init();
}

inheritPrototype(Group, Form);


Group.prototype.init = function() {
  this.element = document.createElement('div');
}

Group.prototype.add = function(child) {
  this.children.push(child);
  this.element.append(child.getElement());
}

Group.prototype.getElement = function() {
  return this.element;
}

 

InputItem 容器構造函數code

var InputItem = function(id, name) {
  Form.call(this);
  this.name = name;
  this.init();
}

inheritPrototype(InputItem, Form);

InputItem.prototype.init = function() {
  this.element = document.createElement('input');
  this.element.id = this.id;
  this.element.type = 'text';
  this.element.name = this.name; 
}

InputItem.prototype.add = function() {}

InputItem.prototype.getElement = function() {
  return this.element;
}

LabelItem 容器構造函數orm

var LabelItem = function(labelFor, labelText) {
  Form.call(this);
  this.labelFor = labelFor;
  this.labelText = labelText;
  this.init();
}

LabelItem.prototype.init = function() {
  this.element = document.createElement('label');
  this.element.htmlFor = this.labelFor;
  this.element.innerText = this.labelText;
}


LabelItem.prototype.add = function() {}

LabelItem.prototype.getElement = function() {
  return this.element;
} 

 

SpanItem 容器構造函數 htm

 

var SpanItem = function(spanText) {
  Form.call(this);
  this.spanText = spanText;
  this.init();
}

inheritPrototype(SpanItem, Form);

SpanItem.prototype.init = function() {
  this.element = document.createElement('span');
  this.element.innerText = this.spanText;
}

SpanItem.prototype.add = function() {}

SpanItem.prototype.getElement = function() {
  return this.element;
} 

 

 

 

代碼已經寫完,稍等,我來測試一下。。。。。。

相關文章
相關標籤/搜索