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章 超值午餐-组合模式 学习笔记的更多相关文章
- javascript设计模式(张容铭)学习笔记 - 外观模式绑定事件
有一个需求要为document对象绑定click事件来是想隐藏提示框的交互功能,于是小白写了如下代码: document.onclick = function(e) { e.preventDefaul ...
- javascript设计模式(张容铭)学习笔记 - 照猫画虎-模板方法模式
模板方法模式(Template Method):父类中定义一组操作算法骨架,而降一些实现步骤延迟到子类中,使得子类可以不改变父类的算法结构的同时可重新定义算法中某些实现步骤. 项目经理体验了各个页面的 ...
- JavaScript高级程序设计第14章表单脚本 (学习笔记)
第十四章 表单脚本 1.阻止默认表单提交 1.提交表单数据 1.使用type=submit提交按钮 2.使用submit():方法 注意:当用户点击提交按钮时,会触发submit事件,从而在这里我们有 ...
- SQL反模式学习笔记14 关于Null值的使用
目标:辨别并使用Null值 反模式:将Null值作为普通的值,反之亦然 1.在表达式中使用Null: Null值与空字符串是不一样的,Null值参与任何的加.减.乘.除等其他运算,结果都是Null: ...
- 《JavaScript设计模式 张》整理
最近在研读另外一本关于设计模式的书<JavaScript设计模式>,这本书中描述了更多的设计模式. 一.创建型设计模式 包括简单工厂.工厂方法.抽象工厂.建造者.原型和单例模式. 1)简单 ...
- CSharp设计模式读书笔记(14):职责链模式(学习难度:★★★☆☆,使用频率:★★☆☆☆)
职责链模式(Chain of Responsibility Pattern):避免请求发送者与接收者耦合在一起,让多个对象都有可能接收请求,将这些对象连接成一条链,并且沿着这条链传递请求,直到有对象 ...
- [Python设计模式] 第19章 分公司=部门?——组合模式
github地址:https://github.com/cheesezh/python_design_patterns 组合模式 组合模式,将对象组合成树形结构以表示"部分-整体" ...
- Java 螺纹第三版 第一章Thread介绍、 第二章Thread创建和管理学习笔记
第一章 Thread导论 为何要用Thread ? 非堵塞I/O I/O多路技术 轮询(polling) 信号 警告(Alarm)和定时器(Timer) 独立的任务(Ta ...
- 《Lua程序设计》第7章 迭代器与泛型for 学习笔记
本章将介绍如何编写适用于泛型for的迭代其(Iterator).7.1 迭代器与closurehttp://www.cnblogs.com/moonlightpoet/p/5685275.html 7 ...
随机推荐
- P4443 [COCI2017-2018#3] Dojave(线段树)
传送门 设\(lim=2^n-1\),对于一个区间\([l,r]\)来说,如果\(sum\neq lim\)且能换出\(x\)并换进\(y\)来,使得\(sum\bigoplus a_x\bigopl ...
- 第一篇 Nosql讲解之Redis,Memchche,MongoDb的区别
本篇文章主要介绍Nosql的一些东西,以及Nosql中比较火的三个数据库Redis.Memchache.MongoDb和他们之间的区别.以下是本文章的阅读目录 一.Nosql介绍 1.Nosql简介 ...
- H - String painter
#include <iostream> #include <algorithm> #include <cstring> #include <cstdio> ...
- 旧版本linaro-ubuntu更改软件源
最近打算研究下arm版本的linaro ubuntu桌面系统,但是在安装软件时速度实在太慢,便想修改一下软件源. 无奈查看系统版本时,显示的是linaro 11.12,但却不知和ubuntu有和关系, ...
- 反射和__setattr__,__delattr__,__getattr__用法
反射 什么是反射:反射的概念是由Smith在1982年首次提出的,主要是指程序可以访问.检测和修改它本身状态或行为的一种能力(自省).这一概念的提出很快引发了计算机科学领域关于应用反射性的研究.它首先 ...
- 洛谷P2514||bzoj2426 [HAOI2010]工厂选址
洛谷P2514 bzoj2426 其实是个简单的贪心,然而不适合在脑子不清醒的时候做...看不懂题意续了1个小时 很容易发现应该枚举新建哪个发电厂,对于这种方案就是取其中b吨煤运到原来发电厂,取剩下( ...
- php设计模式学习之单例模式
某些应用程序资源是独占的,因为有且只有一个此类型的资源.例如,通过数据库句柄到数据库的连接是独占的.您希望在应用程序中共享数据库句柄,因为在保持连接打开或关闭时,它是一种开销,在获取单个页面的过程中更 ...
- Docker容器与容器数据
Docker容器与容器数据 image 与container 镜像(Image)和容器(Container)的关系,就像是面向对象程序设计中的 类 和 实例 一样,镜像是静态的定义,容器是镜像运行时的 ...
- File "<stdin>" , line 1
写了一个hello.py,仅有一句,print 'hello world', 运行 Python hello.py 出错,提示: File "<stdin>" , li ...
- Java之内部类、包及代码块
个人通俗理解: 1.内部类:有点类似于写在父类中的子类,根据位置不一样为不同的名字,和相应的访问方式不同:不过要访问外部类的话,需要充分运用好this(本类)的这个关键字:要是需要快速的创建子类对象的 ...