基于 AMD 规范加载器、jQuery v3.2+ 构建,兼容 IE 9+、ECMAScript 5+、HTML 5+
EWA 模板语法完全沿用各种 Web 前端原生技术的标准语义 ——
UI 结构:HTML 5+ 标准标签、data-*
自定义属性
数据绑定:HTML 标签文本、属性中书写 ECMAScript 6 模板字符串(形如 ${view.propX}
)
事件回调:像绑定数据一样去绑定函数
资源加载:可带参数的 HTTP URL,并自动处理相对路径
MVVM 引擎只需扫描 DOM 树,即可 自动加载 HTML、JSON 来构建 VM 树,开发者专注于数据整理、事件回调即可,无需任何本地编译、打包环境,享受低学习成本的 原生 HTML、JavaScript 开发体验。
ViewModel 是对 View (HTML/DOM) 基于 “数据驱动”模型的面向对象封装 ——
View 的所有 HTML 结构要放在唯一的容器元素中,方便 VM 挂载
同一时刻 View 容器只能挂载一个 VM 对象
VM 在渲染时会检测 JavaScript 数据类型,自动匹配 HTML 模板中对应的 HTML 标签属性、DOM 对象属性
DOM 标准事件、VM 自定义事件的回调函数,也视同数据的一部分绑定到 View,无需专门的 API
View 容器本身的 HTML 标签属于上级 View 的结构,但挂载于其上的 VM 会监听其 data-*=""
自定义属性的数据变更
若不存在指向 解挂的 VM 或摘下的容器元素的其它引用,整个视图将被 自动垃圾回收
以上视图的构造函数 均可从 $.fn.iWebApp
命名空间访问到,并可无需 WebApp()
实例初始化即可单独使用。
$('selector of view').view(Class_Name, iScope)
$(':view', Root_DOM).view()
如下格式的合法 HTTP URL 会被 EWA 引擎理解 ——
path/to/template.html?key1=value1&keyN=valueN&data=/path/to/json
path/to/template.html
、/path/to/json
会被并行加载,{key1: value1, keyN: valueN}
会成为 template.html
对应 VM 初始数据的一部分。
<a target="_blank" href="path/to/outer.html">
新窗口打开外部页面(跨域超链接 默认在新网页中打开)
</a>
<a href="path/to/static.html">
纯静态 SPA 页
</a>
<a href="path/to/template.html">
无初始数据的模板
</a>
<a href="path/to/template.html?data=/path/to/json">
用一份数据初始化一个模板
</a>
<a href="path/to/template.html?key1=value1&keyN=valueN&data=/path/to/json">
用一份数据初始化一个模板,并传入一些参数
</a>
<div id="PageBox"></div>
<script>
$('#PageBox').iWebApp('//api.test.com/v1');
</script>
SPA 页面总是在初始化 WebApp 实例的元素中被加载。
<form method="put" enctype="application/json" action="?data=/path/to/submit">
<input type="hidden" name="extraParam" />
<input type="text" name="key1" required /> 已填 ${view.key1.length} 字
<input type="submit" />
</form>
method
属性支持 RESTful API 规范中的常用 HTTP 动词enctype
属性支持 MIME-Type 标准中的常用类型(如 application/json
)<div data-href="path/to/template.html" data-key1="${view.Key1}" data-keyN="${view.KeyN}">
<span slot="Slot_1"></span>
<span slot="Slot_2"></span>
</div>
EWA 组件支持 Web Components 标准草案的 Slot 机制、自定义属性,但引用时无需自定义标签。
<a data-method="PUT" href="?data=/path/to/put">点个赞</a>
<h3>列个表</h3>
<div data-href="?data=/path/to/list?count=10&page=1">
<ul data-name="list">
<li>内置索引号:${view.__index__}</li>
</ul>
共 ${view.total} 项
</div>
利用 HTML 5 History API 对“纯 Hash URL”的支持,EWA 引擎直接把 SPA 页面 URL 置于 #!
(Hash Bang,Google 提出的纯前端路由规则)之后,即使无后端渲染支持,用户也可随意【F5】或【Ctrl + C/V】。
(new EWA()).on({
type: 'request',
src: 'api.test.com'
}, function (iEvent, iAJAX) {
// 基于 iQuery 扩展的实用方法,处理 jQuery AJAX 选项对象
iAJAX.option.url = $.extendURL(iAJAX.option.url, {
token: self.sessionStorage.token
});
});
(new EWA()).on({
type: 'template',
href: /\.md$/i
}, function (iEvent, iData) {
// MarkDown 转 HTML
return marked( iData );
}).on({
type: 'data',
src: 'api.test.com'
}, function (iEvent, iData) {
if (iData.code || (iEvent.method != 'GET'))
self.alert( iData.message );
else
return iData.data;
});
(new EWA()).on({
type: 'ready',
href: 'path/to/template.html'
}, function (iEvent) {
// 一个组件/页面的 DOM Ready
// 即除 img、iframe、audio、video 等多媒体资源的 UI 渲染完成
});
获取 页面路由原文:WebApp.prototype.getRoute()
修改 路由初始数据:WebApp.prototype.setURLData(key, value)
调用时可只传一个数据对象
每次调用都生成一条新浏览历史
页面浏览历史 导航:WebApp.prototype.loadPage( iStep )
不传参时刷新当前页
传参时,参数与 window.history.go()
的用法一致
页面切换后会重新加载,并解决本方法返回的 Promise 对象
EWA 组件代码本身是完全合法的 HTML 片段,可直接被 AJAX 加载并在 DOM 树中实例化 ——
<style disabled>
/* 此处的 disabled 标准属性是为了防止 DOM 子树初始化时影响全局 CSS,
* 组件 VM 对象初始化时会自动生成 CSS 作用域
*/
</style>
<!--
一个组件只有一份 JS 代码,推荐写在其 HTML 文件同目录的同名 .js 文件中
-->
<script src="component.js"></script>
<!--
组件 UI 结构完全是普通的 HTML、JavaScript 表达式
-->
<div>
现在是 ${(new Date()).toLocaleString()}
<slot name="Slot_1" />
</div>
无论 EWA 引擎本身,还是 EWA 组件的 JS 代码,均遵循 AMD 规范,其必要格式如下 ——
require([
'jquery', 'Module_1', 'Module_N', 'EasyWebApp'
], function ($, Module_1, Module_N, EWA) {
// 获取已初始化的 WebApp 单例
var iWebApp = new EWA();
EWA.component(function (iData) {
// iData 是与组件 HTML 并行加载的 JSON
// 此处的 this 是自动创建好的 VM 对象
var VM = this;
iData.handler_1 = function () {
// 回调函数也可以作为数据的一部分,用同样的模板语法绑定到 HTML 上
// 此处的 this 还是 VM 对象
this.xxx = 'yyy';
};
// 若你改变了传入的数据对象的引用,就必须 return 新的对象
iData = $.extend({ }, iData);
return iData;
});
});
EWA 引擎会自动用它返回的数据对象来更新 VM。
声明式事件绑定的统一形式:<element onEvent="${view.callback}" />
element
:HTML 标签名Event
:HTML / EWA 事件名callback
:事件回调在数据对象中的键名,该函数运行时 this
指向 element
在 HTML 结构上所处视图的 VM 对象事件名 | 来源对象 | 监听方式 | 触发原因 | 触发阶段 | 回调数据 |
---|---|---|---|---|---|
request | InnerLink | JS、HTML | AJAX 请求 | 之前 | jQuery AJAX 选项、jqXHR 对象 |
template | HTMLView | JS、HTML | 组件模板 | 之后 | 组件结构代码(如 HTML、MarkDown) |
data | InnerLink | JS、HTML | 数据加载 | 之后 | JSON 对象 |
ready | View | JS、HTML | 组件渲染 | 之后 | 视图对象 |
route | WebApp | JS | 路由切换 | 之后 | 当前页匹配的超链接元素集合(jQuery 对象) |
prefetch | WebApp | JS | 组件渲染 | 之后 | 当前组件引用的超链接 URL 数组 |
attach | View | JS | 组件挂载 | 之后 | |
detach | View | JS | 组件卸载 | 之后 | |
update | View | JS、HTML | 自定义属性更新 | 之后 | 更新的键值对 |
多条件观察者 Observer($_Box)
查找实例:.instanceOf(iDOM, Check_Parent)
注册回调:.prototype.on(iEvent, iCallback)
this
指向注册时的对象注销回调:.prototype.off(iEvent, iCallback)
一次监听:.prototype.one(iEvent, iCallback)
触发事件:.prototype.emit(iEvent, iData)
实现类:View
、InnerLink
、WebApp
上述 iEvent
参数可仅为一个事件名字符串,也可用一个对象描述更多的条件(对象属性值可为字符串、正则表达式、DOM 对象等)。
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。
1. 开源生态
2. 协作、人、软件
3. 评估模型