刀耕火种

刀耕火种是新石器时代残留的农业经营方式。又称迁移农业,为原始生荒耕作制。
var TodoApp = Nuclear.create({
    add: function (evt) {
        evt.preventDefault();
        var textBox = this.node.querySelector('input');
        this.option.items.push(textBox.value);
    },
    installed: function () {
        var form = this.node.querySelector('form');
        form.addEventListener('submit', this.add.bind(this), false);
    },
    render: function () {
        return '<div>\
                 <h3>TODO</h3>\
                 <ul> {{#items}} <li>{{.}}</li> {{/items}}</ul>\
                  <form >\
                   <input type="text"  />\
                   <button>Add #{{items.length}}</button>\
                 </form>\
                </div>';
    }
});

new TodoApp( { items: [] },"#container");

这种书写方式依赖延续了jQuery时代的思维方式:

  • js里查找dom
  • js里绑定事件

在以前的文章里写过,如果不使用组件化编程,js里查找dom以及在js里绑定事件可能会带来如下问题:

  • 浪费带宽
  • 用户反馈无响应
  • 脚本错误
  • 页面短暂错乱

上面的书写方式粗暴、原始、落后,即:刀耕火种。

石器锄耕

“石器锄耕”是奴隶社会时期的主要耕作方式,这一时期农业已经有了很大的发展。
var TodoApp = Nuclear.create({
    onRefresh: function () {
        this.form.addEventListener("submit", function (evt) {
            evt.preventDefault();
            this.option.items.push(this.textBox.value);
        }.bind(this), false);
    },
    render: function () {
       return '<div>\
                 <h3>TODO</h3>\
                 <ul> {{#items}} <li>{{.}}</li> {{/items}}</ul>\
                 <form nc-id="form" >\
                   <input nc-id="textBox" type="text"  />\
                   <button>Add #{{items.length}}</button>\
                 </form>\
               </div>';
    }
},{
    diff:false
});

new TodoApp( { items: [] },"#container");

会发现,查找dom的代码已销声匿迹。直接标记nc-id,就自动挂载在this下。
值得注意的是,传入了第二参数关闭了DOM diff。关掉diff的结果就是,每次组件HTML会全部重新替换渲染,绑定的事件全部丢失,所以需要将绑定事件的代码写入onRefresh里,这样每次重新渲染都会再绑定一次。
比刀耕火种先进一点:石器锄耕。

直捣黄龙

黄龙:即黄龙府,辖地在今吉林一带,应该是指长春市农安县,为金人腹地。一直打到黄龙府。指捣毁敌人的巢穴。指杀敌取胜。
var TodoApp = Nuclear.create({
    add: function (evt) {
            evt.preventDefault();
            this.option.items.push(this.textBox.value);
    },
    render: function () {
       return '<div>\
                 <h3>TODO</h3>\
                 <ul> {{#items}} <li>{{.}}</li> {{/items}}</ul>\
                 <form onsubmit="add(event)" >\
                   <input nc-id="textBox" type="text"  />\
                   <button>Add #{{items.length}}</button>\
                </form>\
               </div>';
    }
});

new TodoApp( { items: [] },"#container");

会发现,查找dom和绑定的代码同时销声匿迹!!

  • 需要使用input,直接标记nc-id为textBox,就可以this.textBox访问
  • 需要绑定事件,直接在HTML内声明事件和回调onsubmit="add(event)"

也可以通过add(event,this)拿到event和触发该事件的dom元素。

代码通俗简洁干净直接,目的直观明确。故:直捣黄龙。

子承父业

宋·释道原《景德传灯录·利山和尚》:“僧问:不历僧只获法身,请师直指。师云:子承父业。”
var TodoList = Nuclear.create({
    render: function () {
        return '<ul> {{#items}} <li>{{.}}</li> {{/items}}</ul>';
    }
});

var TodoApp = TodoList.create({
    add: function (evt) {
        evt.preventDefault();
        this.option.items.push(this.textBox.value);
    },
    render: function () {
        return '<div>\
                 <h3>TODO</h3>'
                + this._super.render() +
                '<form  onsubmit="add(event)" >\
                   <input nc-id="textBox" type="text"  />\
                   <button>Add #{{items.length}}</button>\
                 </form>\
               </div>';
    }
});

new TodoApp({ items: [] },"#container");

TodoApp不过是TodoList的炎黄子孙,故TodoApp可以通过this._super访问父辈。也可访问父辈任何方法。有人会说:“组合”优于“继承”的。一定要明白:OOP既能组合也能继承,是不冲突的。且看下面例子。

万夫一力

明·刘基 《郁离子·省敌》:“万夫一力,天下无敌。”
var TodoList = Nuclear.create({
    render: function () {
        return '<ul> {{#items}} <li>{{.}}</li> {{/items}}</ul>';
    }
});

var TodoApp = Nuclear.create({
    install: function () {
        this.todoList = new TodoList({ items: [] })
    },
    add: function (evt) {
            evt.preventDefault();
            this.todoList.option.items.push(this.textBox.value);
            this.refresh();
    },
    render: function () {
       return '<div>\
                 <h3>TODO</h3>'
                 + this.todoList.render()+
                 '<form onsubmit="add(event)" >\
                   <input nc-id="textBox" type="text"  />\
                   <button>Add #'+this.todoList.option.items.length+'</button>\
                 </form>\
               </div>';
    }
});

new TodoApp( {},"#todo2Container");

前一个例子的继承,这个例子是组合。不能说你的框架是Class base就不能使用组合,这是天大的误解。而我依稀记得极限编程关于面向对象设计的推论是:优先使用对象组合,而不是类继承。作为框架的设计者,虽然会有一些约束,但是如果连组合和继承都不能共存,那就是设计的最大败笔。
使用Nuclear既能继承也能组合,关键看程序逻辑该怎么抽象和实现复杂度。

藕断丝连

唐·孟郊《去妇》诗:“妾心藕中丝;虽断犹牵连。”
var TodoList = Nuclear.create({
    render: function () {
        return '<ul> {{#items}} <li>{{.}}</li> {{/items}}</ul>';
    }
});

var TodoApp = Nuclear.create({
    install: function () {
        this.todoList = new TodoList(this.option)
    },
    add: function (evt) {
            evt.preventDefault();
            this.option.items.push(this.textBox.value);
    },
    render: function () {
       return '<div>\
                 <h3>TODO</h3>'
                 + this.todoList.render()+
                 '<form  onsubmit="add(event)"  >\
                   <input nc-id="textBox" type="text"  />\
                   <button>Add #{{items.length}}</button>\
                 </form>\
               </div>';
    }
});

new TodoApp( { items: [] },"#container");

这个例子和上个例子的区别是:共用option。option的变更会自动更新依赖option的组件。

四海为家

 《汉书·高帝记》:“且夫天子以四海为家。”
var TodoApp = Nuclear.create({
add: function (evt) {
        evt.preventDefault();
        this.option.items.push(this.textBox.value);
},
render: function () {
   return '<div>\
             <h3>TODO</h3>\
             <ul> {{#items}} <li>{{.}}</li> {{/items}}</ul>\
             <form onsubmit="add(event)" >\
               <input nc-id="textBox" type="text"  />\
               <button>Add #{{items.length}}</button>\
             </form>\
           </div>';
}
});
var todo= new TodoApp( { items: [] });

todo.setNuclearContainer('#container');

且看上面的new TopApp没传第二个参数指定容器。后面使用setNuclearContainer指定容器。这个场景还是比较常见,创建游离态组件,后续根据需要指定容器。AlloyLever就是这么干的: https://github.com/AlloyTeam/AlloyLever/blob/master/src/js/main.js

如虎添翼

三国·蜀·诸葛亮《心书·兵机》:“将能执兵之权,操兵之势,而临群下,臂如猛虎加之羽翼,而翱翔四海。”
var TodoApp = Nuclear.create({
    add: function (evt) {
        evt.preventDefault();
        this.option.items.push(this.textBox.value);
    },
    render: function () {
        return '<div>\
                  <h3>TODO</h3>\
                  <ul> {{#items}} <li>{{.}}</li> {{/items}}</ul>\
                  <form onsubmit="add(event)" >\
                   <input nc-id="textBox" type="text"  />\
                   <button>Add #{{items.length}}</button>\
                 </form>\
               </div>';
    },
    style: function () {
        return 'h3 { color:red; }\
                button{ color:green;}';
    }
});
var todoApp = new TodoApp({ items: [] }, '#container');

todoApp.option.items.push('Nuclear');
todoApp.option.items.push('Hello World!');

style方法内的样式自会对自身生效,不会污染其他组件。可以操作对象实例option,option的变更会自动更新组件,属性设置>方法调用。
双向绑定的好处以前写过一篇文章专门介绍,从上面的例子也能可出:

  • 组件内部的代码更简洁
  • 组件外部的代码更简洁

壁垒森严

壁垒:古代军营四周的围墙;森严:整齐,严肃。原指军事戒备严密。现也用来比喻彼此界限划得很分明。
<template id="myTemplate">
    <style scoped>
        h3 { color:red; }
        button{ color:green;}
    </style>

    <div>
        <div>
            <h3>TODO</h3>
            <ul>{{#items}}<li>{{.}}</li>{{/items}}</ul>
            <form onsubmit="add(event)">
                <input nc-id="textBox" type="text">
                <button>Add #{{items.length}}</button>
            </form>
        </div>
    </div>
</template>

<script>
    var TodoApp = Nuclear.create({
        install:function() {
            this.todoTpl = document.querySelector("#myTemplate").innerHTML;
        },
        add: function (evt) {
            evt.preventDefault();
            this.option.items.push(this.textBox.value);
        },
        render: function () {
            return this.todoTpl;
        }
    });

    new TodoApp({ items: [] }, "#todoListContainer");
</script>

不用担心template标签的兼容性问题,Nuclear帮你处理好了。支持所有现代浏览器(包括IE9+)。
Nuclear也在js里进行了动态插入了template { display: none !important; }。但是js还没执行到且浏览器不兼容template的话,用户会看到一闪而过的模板原始代码。
所以为了避免IE9一闪而过的模板原始代码直接显示,建议在head中加入。

<style>
    template {
        display: none !important;
    }
</style>

如果你像手Q hybrid应用那样只需要兼容webkit的话,天生支持template,就不用加入上面的兼容样式。

鬼斧神工

《庄子·达生》:“梓庆削木为鐻,鐻成,见者惊忧鬼神。”
var TodoApp = Nuclear.create({
    add: function (evt) {
        evt.preventDefault();
        this.option.items.push(this.textBox.value);
    },
    render: function () {
        return `<div>
                  <h3>TODO</h3>
                  <ul> {{#items}} <li>{{.}}</li> {{/items}}</ul>
                  <form onsubmit="add(event)" >
                   <input nc-id="textBox" type="text"  />
                   <button>Add #{{items.length}}</button>
                 </form>
               </div>`;
    },
    style: function () {
        return `h3 { color:red; }
                button{ color:green;}`;
    }
});

人剑合一

剑修者最高境界,人既是剑,剑既是人,剑随心发,人随剑杀
var TodoApp = Nuclear.create({
    add: function (evt) {
        evt.preventDefault();
        this.option.items.push(this.textBox.value);
    },
    render: function () {
        return `<style scoped>
                  h3 { color:red; }
                  button{ color:green;}
                </style>
                <div>
                  <h3>TODO</h3>
                  <ul> {{#items}} <li>{{.}}</li> {{/items}}</ul>
                  <form onsubmit="add(event)" >
                   <input nc-id="textBox" type="text"  />
                   <button>Add #{{items.length}}</button>
                 </form>
                </div>`;
    }
});

Nuclear从出生,API简单稳定,几乎没怎么变动,内部是实现在不断的完善,API驱动非常重要,不能因为实现某些API困难而做任何妥协,比如让使用框架的着多传个参数、多调用一次方法,这都是设计的缺陷。

Nuclear就是不妥协的结果。因为简单的设计,所以可以有很多强大的玩法,待续...

广而告之

Nuclear Github: https://github.com/AlloyTeam/Nuclear

加入Nuclear,一起让组件化开发体验更加惬意、舒适..

基于Nuclear的Web组件-Todo的十一种写法的更多相关文章

  1. 基于JS实现回到页面顶部的五种写法(从实现到增强)

    这篇文章主要介绍了基于JS实现回到页面顶部的五种写法(从实现到增强)的相关资料,本文介绍的非常详细,实用性也非常高,非常具有参考借鉴价值,需要的朋友可以参考下   写法 [1]锚点 使用锚点链接是一种 ...

  2. 基于接口的 InvocationHandler 动态代理(换种写法)

    InvocationHandler is the interface implemented by the invocation handler of a proxy instance. Each p ...

  3. 基于继承的 MethodInterceptor 动态代理(换种写法)

    net.sf.cglib.proxy.Enhancer Generates dynamic subclasses to enable method interception. This class s ...

  4. 10.Web组件复用

    1.静态包含(一个指令) 在软件工程中构建可复用组件可极大的提高软件生产效率.增强系统的可维护性HTML标记对于一个web应用系统中的页面都是通用的,比如公司标志.版权声明.导航菜单JSP中引用的we ...

  5. Web组件的三种关联关系

    Web应用程序如此强大的原因之一是它们能彼此链接和聚合信息资源.Web组件之间存在三种关联关系: ●  请求转发 ●  URL重定向 ●  包含 存在以上关联关系的Web组件可以是JSP或Servle ...

  6. 漫谈Nuclear Web组件化入门篇

    目前来看,团队内部前端项目已全面实施组件化开发.组件化的好处太多,如:按需加载.可复用.易维护.可扩展.少挖坑.不改组件代码直接切成服务器端渲染(如Nuclear组件化可以做到,大家叫同构)... 怎 ...

  7. RSuite 一个基于 React.js 的 Web 组件库

    RSuite http://rsuite.github.io RSuite 是一个基于 React.js 开发的 Web 组件库,参考 Bootstrap 设计,提供其中常用组件,支持响应式布局. 我 ...

  8. Amaze UI 发布基于jQuery新版本v2.0.0之web组件

    首先Amaze Ui第一版时我收到邮件邀请去试用,去了官网看了下,是基于zepto.js的一个类似bootstrap的响应式框架,提到框架当然是好事,快速开发呗.这词2.0的弃用zepto.js改用j ...

  9. SpringMVC内容略多 有用 熟悉基于JSP和Servlet的Java Web开发,对Servlet和JSP的工作原理和生命周期有深入了解,熟练的使用JSTL和EL编写无脚本动态页面,有使用监听器、过滤器等Web组件以及MVC架构模式进行Java Web项目开发的经验。

    熟悉基于JSP和Servlet的Java Web开发,对Servlet和JSP的工作原理和生命周期有深入了解,熟练的使用JSTL和EL编写无脚本动态页面,有使用监听器.过滤器等Web组件以及MVC架构 ...

随机推荐

  1. jQuery radio的取值与赋值

    取值: $("input[name='radioName']:checked").val(); 赋值: $("input[name='radioName'][value= ...

  2. Hadoop的安装与设置(1)

    在Ubuntu下安装与设置Hadoop的主要过程. 1. 创建Hadoop用户 创建一个用户,用户名为hadoop,在home下创建该用户的主目录,就不详细介绍了. 2. 安装Java环境 下载Lin ...

  3. 超详细mysql left join,right join,inner join用法分析

    下面是例子分析表A记录如下: aID        aNum 1           a20050111 2           a20050112 3           a20050113 4   ...

  4. MyBatis2:config.xml文件

    前言 前一篇文章,讲了MyBatis入门,讲到了MyBatis有两个基本的配置文件,一个用来配置环境信息,一个用来写SQL语句.前者我把它命名为config.xml,config.xml的内容是: & ...

  5. .NET全栈开发工程师学习路径

    PS:最近一直反复地看博客园以前发布的一条.NET全栈开发工程师的招聘启事,觉得这是我看过最有创意也最朴实的一个招聘启事,更为重要的是它更像是一个技术提纲,能够指引我们的学习和提升,现在转载过来与各位 ...

  6. JAAS 是个什么梗

    参考资料 该文中的内容来源于 Oracle 的官方文档.Oracle 在 Java 方面的文档是非常完善的.对 Java 8 感兴趣的朋友,可以从这个总入口 Java SE 8 Documentati ...

  7. [转]Fiddler抓取Android真机上的HTTPS包

    此篇文章转载自:http://blog.csdn.net/roland_sun/article/details/30078353 工作中经常会需要对一些app进行抓包, 但是每次默认都是只抓http请 ...

  8. backup3:master 数据库的备份和还原

    在SQL Server 中,master 数据库记录系统级别的元数据,例如,logon accounts, endpoints, linked servers, and system configur ...

  9. 【.net深呼吸】WPF异步加载大批量图像

    如何在WPF中加载大批量数据,并且不会阻塞UI线程,尤其是加载大量图片时,这活儿一直是很多朋友都相当关注的.世上没有最完美的解决之道,咱们但求相对较优的方案. 经过一些试验和对比,老周找到了一种算是不 ...

  10. 新项目的CQRS设计

    刚换了个工作,闲话不说了.前两天开始一个新项目,大概是一个任务管理系统,由使用者来选取任务,执行任务,反馈完成,我大概做了些设计,本来是打算看能不能在新公司铺垫一下DDD,不过后来这块功能没分到我这, ...