javascript设计模式(张容铭) 第14章 超值午餐-组合模式 学习笔记

时间:2023-03-09 04:10:30
javascript设计模式(张容铭) 第14章 超值午餐-组合模式 学习笔记

JS 组合模式更常用于创建表单上,比如注册页面可能有不同的表单提交模块。对于这些需求我们只需要有基本的个体,然后通过一定的组合即可实现,比如下面这个页面样式(如图14-2所示),我们来用组合模式实现。

作者给的提示,首先创建基类 Base, 然后三个组合类 FormItem、FieldsetItem、Group,以及成员类InputItem、LabelItem、SpanItem、TextareaItem,创建完之后像下面这样拼出你的注册页面吧。

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 容器构造函数

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 容器构造函数

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 容器构造函数

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 容器构造函数

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 容器构造函数

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 容器构造函数 

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;

javascript设计模式(张容铭) 第14章 超值午餐-组合模式 学习笔记

代码已经写完,稍等,我来测试一下。。。。。。