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章 超值午餐-组合模式 学习笔记的更多相关文章

  1. javascript设计模式(张容铭)学习笔记 - 外观模式绑定事件

    有一个需求要为document对象绑定click事件来是想隐藏提示框的交互功能,于是小白写了如下代码: document.onclick = function(e) { e.preventDefaul ...

  2. javascript设计模式(张容铭)学习笔记 - 照猫画虎-模板方法模式

    模板方法模式(Template Method):父类中定义一组操作算法骨架,而降一些实现步骤延迟到子类中,使得子类可以不改变父类的算法结构的同时可重新定义算法中某些实现步骤. 项目经理体验了各个页面的 ...

  3. JavaScript高级程序设计第14章表单脚本 (学习笔记)

    第十四章 表单脚本 1.阻止默认表单提交 1.提交表单数据 1.使用type=submit提交按钮 2.使用submit():方法 注意:当用户点击提交按钮时,会触发submit事件,从而在这里我们有 ...

  4. SQL反模式学习笔记14 关于Null值的使用

    目标:辨别并使用Null值 反模式:将Null值作为普通的值,反之亦然 1.在表达式中使用Null: Null值与空字符串是不一样的,Null值参与任何的加.减.乘.除等其他运算,结果都是Null: ...

  5. 《JavaScript设计模式 张》整理

    最近在研读另外一本关于设计模式的书<JavaScript设计模式>,这本书中描述了更多的设计模式. 一.创建型设计模式 包括简单工厂.工厂方法.抽象工厂.建造者.原型和单例模式. 1)简单 ...

  6. CSharp设计模式读书笔记(14):职责链模式(学习难度:★★★☆☆,使用频率:★★☆☆☆)

    职责链模式(Chain of Responsibility  Pattern):避免请求发送者与接收者耦合在一起,让多个对象都有可能接收请求,将这些对象连接成一条链,并且沿着这条链传递请求,直到有对象 ...

  7. [Python设计模式] 第19章 分公司=部门?——组合模式

    github地址:https://github.com/cheesezh/python_design_patterns 组合模式 组合模式,将对象组合成树形结构以表示"部分-整体" ...

  8. Java 螺纹第三版 第一章Thread介绍、 第二章Thread创建和管理学习笔记

    第一章 Thread导论 为何要用Thread ? 非堵塞I/O      I/O多路技术      轮询(polling)      信号 警告(Alarm)和定时器(Timer) 独立的任务(Ta ...

  9. 《Lua程序设计》第7章 迭代器与泛型for 学习笔记

    本章将介绍如何编写适用于泛型for的迭代其(Iterator).7.1 迭代器与closurehttp://www.cnblogs.com/moonlightpoet/p/5685275.html 7 ...

随机推荐

  1. pytest入门学习(2)

    pytest的hello world pyt1.py def func(x): print (x+1); return x+1; def test_answer(): assert func(3) = ...

  2. mysql之SQL入门与提升(四)——终结篇,函数

    一.SQL Aggregate (聚合)函数 SQL Aggregate 函数计算从列中取得的值,返回一个单一的值. AVG() - 返回平均值 COUNT() - 返回行数 FIRST() - 返回 ...

  3. urllib库的基本使用

    urllib库的使用 官方文档地址:https://docs.python.org/3/library/urllib.html 什么是urllib Urllib是python内置的HTTP请求库包括以 ...

  4. ZROI #364. 【2018普转提day18专题】嘤嘤嘤

    ZROI #364. [2018普转提day18专题]嘤嘤嘤 直接贴代码 具体见注释 #include<stdio.h> #include<cstring> #include& ...

  5. 运用session来控制用户的异地登录被挤下线情况

    在用QQ的过程中我们如果你的账号在另外一台手机上面登录,这是腾讯后台会提醒你异地登录,可能你的账号被盗了,然后你手机上得QQ就会被退出登录,这个时候你就需要重新登录修改密码,以确保账号的安全.那这种被 ...

  6. hihocoder #1190 : 连通性·四 点双联通分量

    http://hihocoder.com/problemset/problem/1190?sid=1051696 先抄袭一下 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描 ...

  7. HackerRank Super Six Substrings dp

    https://www.hackerrank.com/contests/hourrank-18/challenges/super-six-substrings 能被6整除的数有一个特点,就是能同时被3 ...

  8. Memcached 未授权访问漏洞及加固

    memcached是一套分布式的高速缓存系统.它以Key-Value(键值对)形式将数据存储在内存中,这些数据通常是应用读取频繁的.正因为内存中数据的读取远远大于硬盘,因此可以用来加速应用的访问. 漏 ...

  9. 将Form以强类型Model提交,后台获取不到的问题

    F.TextBoxFor(m => m.Name) 不能自定ID属性

  10. SpringBoot实现登陆拦截

    一.创建interceptor包,在interceptor中创建一个拦截器并实现HandlerInterceptor 代码: @Componentpublic class LoginHandlerIn ...