entity-frame
欢迎使用entity-frame框架,如果是使用过asp.net core的mvc框架的码友应该会有亲切感,本框架还在测试阶段,Bug欢迎留言反馈,给你们带来的麻烦我十分抱歉。邮箱:19815488@qq.com。
2.0 后将使用ES6的标准重新编写。
无http服务版本、http/https服务移步:https://www.npmjs.com/package/internet-information-services
Bug记录
2017.12.21 影响版本 0.8.17- 没有opt.localDB和opt.mongoDB引起的错误
2017.12.23 影响版本 0.8.24- 没有mongoDB Cursor Closed引起的错误
2018.01.09 影响版本 1.1.0- IE浏览器下mime类型的错误。
新变动
- mongodb版本
1.1.6
mongodb使用3.0以上版本
- 返回mongodb对象
1.1.3
如果使用mongodb的话会在context.onsuccess返回mongodb对象。
mongodb.ObjectId(id)
- 添加mime类型的对象
1.1.0
opt.mime = {mp3: "audio/mpeg"};
- 增加全局对象 global 可在路由方法和视图中使用
0.9.0 添加自动生成{static}/index.html,加入 测试记录.html 文件
opt.global
数据库支持
本框架支持indexeddb或mongoDB
npm install indexeddb-js sqlite3
npm install mongodb
实例
引用框架
var ef = require("entity-frame");
初始化
var context = ef.init( //初始化
{
project: project, //Object (必须) 项目主体
// gateway: gateway, //Function 每次网络请求都会调用此回调
// port: 8080, //String,Number 监听端口
// static: "wwwroot", //String 静态文件目录
// mime: {mp3: "audio/mpeg"}, //Object mime类型的对象
// html: '{/head}\n\n{/foot}', //String 自定义全局模板
// shared: shared, //Array 共享模板数组
// global: global, //Onject 全局对象
// lang: "zh-cn", //String 本地化
// charset: "UTF-8", //String html编码
// localDB: "idb" //String 本地数据库名称
// mongoDB: "mongodb://localhost:27017/mdb" //String mongoDB数据库连接字符串
}
);
context.onsuccess = function (db, mongodb) { //数据库连接成功回调,如果使用mongodb的话会返回mongodb对象。
console.log("数据库连接成功。");
};
参数详细说明
opt.gateway
...
gateway: function (scope) {
scope.Auth //Object 身份验证信息
scope.global //Object 全局对象
scope.controller //String 控制器名称
scope.action //String 方法名称
scope.filter //String 过滤器名称
scope.id //String id值
scope.method //String 请求方法 get、post、put、delete
scope.redirect //Function 重定向方法 arg1=/*url*/
scope.request //Object Node.js http的request对象
scope.response //Object Node.js http的response对象
scope.request.headers["content-length"] //Int 请求数据的大小
return false; //将拒绝该次请求
},
...
实例
function gateway(scope) {
if (scope.Auth.Role !== "admin" && scope.controller === "admin" && scope.action !== "login") {
scope.redirect("/admin/login");
return false;
}
if (scope.Auth.Role !== "admin"
&& (scope.controller === "user" && scope.action === "list")) {
scope.redirect("/home");
return false;
}
...
//也可以在这里编写防攻击、恶意访问逻辑,return false;将拒绝该次请求
}
opt.post 设置监听端口默认值为 80
opt.static 设置静态目录默认值为 "wwwroot"
opt.html 设置自定义全局模板
默认值为:
<!DOCTYPE html>
<html lang="{lang}">
<head>
<meta charset="{charset}">
<title>{controller} - {action} {filter}</title>
</head>
<body>
</body>
</html>
opt.lang 设置默认模板的本地化
opt.charset 设置默认模板的编码
opt.localDB 使用本地数据库indexeddb的数据库名称,须引用 npm install indexeddb-js sqlite3,如果不使用就不用引入。
opt.mongoDB 使用mongoDB的连接字符串,须引用npm install mongodb@2.2.33,暂时支持2.2.33,还需打开mongoDB服务,移步http://www.runoob.com/mongodb/mongodb-window-install.html,如果不使用就不用引入。
- 重要参数
opt.shared 共享模板目录
引用结构:{/{path}/{file}}
模板文件将自动生成在views下shared文件夹中
opt.shared = ["head", "foot", "user/head", "user/foot", "templet/partial/page"];
自动生成的文件结构
views ─ shared ┬ head.html
├ foot.html
├ user ─────┬ head.html
│ └ foot.html
└ templet ─── partial ── page.html
实例
<html>
{/user/head}
<div>内容1</div>
{/templet/partial/page}
<div>内容2</div>
{/foor}
</html>
opt.project 项目的主要重要结构和逻辑处理中心
路由结构:://{domain}/{controller}/{action}/{filter}/{id}
var project = {
controller1: {
action1: {
filter1: ...,
filter2: ...,
...
},
action2: ...,
...
},
controller2: ...,
...
};
视图文件将自动生成在views文件夹中
views ┬ controller1 ┬ action1 ┬ filter1
│ │ ├ filter2
│ │ └ ...
│ ├ action2
│ │
│ └ ...
├ controller2
│
└ ...
实例1
var project = { //大小写不敏感
LOG: {
Add: function (scrop) { // todo },
list: function (scrop) { // todo }
},
admin: function (scrop) { // todo },
user: {
index: null,
login: function (scrop) { // todo },
logon: function (scrop) { // todo },
logout: function (scrop) { // todo },
vip: {
index: null,
logout: null
},
svip: {
index: null,
logout: function (scrop) { // todo }
}
}
};
自动生成的文件结构
views ┬ log ──┬─── add.html
│ └── list.html
├ admin ── index.html
└ user ─┬─ index.html
├─ login.html
├─ logon.html
├ logout.html
├ vip ────────┬─ index.html
│ └ logout.html
└ svip ───────┬─ index.html
└ logout.html
请求(实例1)
参数方式1:filter, id;
://domain/log/list/user/201712
路由到方法 project.log.list(scope)
方法中使用:
scope.where(l => l.filter === scope.filter && l.data >= scope.id).onsuccess = function (list) {
list.forEach(log) { //todo };
};
页面内使用
<html>
<body>
<h2>{filter}</h2>
日期:{id}
...
</body>
</html>
参数方式2:querystring;
://domain/log/list?filter=user&date=201712
路由到方法 project.log.list(scope)
方法中使用:
scope.where(l => l.filter === scope.query.filter && l.data >= scope.query.date).onsuccess = function (list) {
list.forEach(log) { //todo };
};
页面内使用
<html>
<body>
<h2>{query.filter}</h2>
日期:{query.date}
...
</body>
</html>
参数方式3:data; //post,put,delete
://domain/log/list
路由到方法 project.log.list(scope)
方法中使用:
scope.where(l => l.filter === scope.data.filter && l.data >= scope.data.date).onsuccess = function (list) {
list.forEach(log) { //todo };
};
//文件上传处理
scope.data.file1.save("file", "f1.jpg");//异步处理
//scope.data.file1.save("file", "f1.jpg", true);//同步处理
//参数缺省,如:<input type="file" name="i1" /> //type: image/jpeg
//scope.data.file1.save("file"); 等价 scope.data.file1.save("file", "i1.jpeg");
页面内使用
<html>
<body>
<h2>{data.filter}</h2>
日期:{data.date}
...
</body>
</html>
参数方式4:混合使用
://domain/log/list/user?date=201712
路由到方法 project.log.list(scope)
方法中使用:
scope.where(l => l.filter === scope.filter && l.data >= scope.query.date).onsuccess = function (list) {
list.forEach(log) { //todo };
};
//文件上传处理
scope.data.file1.save("file", "f1.jpg");//异步处理
//scope.data.file1.save("file", "f1.jpg", true);//同步处理
//参数缺省,如:<input type="file" name="i1" /> //type: image/jpeg
//scope.data.file1.save("file"); 等价 scope.data.file1.save("file", "i1.jpeg");
页面内使用
<html>
<body>
<h2>{filter}</h2>
日期:{data.date}
...
</body>
</html>
服务器端脚本
<script server>
// todo
</script>
循环5个div
1、//不推荐
<script server>
for (var i = 0; i < 5; i++)
<div>{id}</div>
</script>
2、//推荐
<script server>
for (var i = 0; i < 5; i++)
'<div>{0}</div>'.format(i);
</script>
3、
<script server>
for (var i = 0; i < 5; i++)
document.write('<div>{0}</div>'.format(i));
</script>
可以使用路由到的方法传递过来的数据,默认为scope的数据
<script server>
"" + scope.method;
"name: {query.name}, age: {query.age}.".format(scope);
if (!scope.Auth.user)
scope.redirect("/user/login");
else
'<h4>登录成功,正在跳转</h4><meta http-equiv="Refresh" content="1; url=/home" />';
</script>
数据库使用
如果配置了数据库context.onsuccess会返回一个数据库context实例,数据库自动按照控制器生成对应的数据表,context里面就有相应的表实体。
如 实例1:
context.user
context.admin
context.log
- 增
context.log.add({title: "Login", date: Date.now()}).onsuccess = function (ev) {};
context.log.add([{title: "Logon", date: Date.now()}, {title: "Login", date: Date.now()}]).onsuccess = function (ev) {};
//在controller对应的action中
scope.add({title: "Login", date: Date.now()}).onsuccess = function (ev) {};
scope.add([{title: "Logon", date: Date.now()}, {title: "Login", date: Date.now()}]).onsuccess = function (ev) {};
- 查
查一个
context.user.default(u => u.uid === Uid && u.pwd === Pwd).onsuccess = function (result) {
if (result === null)
;// todo
else
;// todo
}
//在controller对应的action中
scope.default(u => u.uid === scope.data.uid && u.pwd === scope.data.pwd).onsuccess = function (result) {
if (result === null)
;// todo
else
;// todo
}
查多个
context.log.where(l => l.title === "Login").onsuccess = function (arr) {
arr.forEach(function (l) { // todo });
}
//在controller对应的action中
scope.where(l => l.title === "Login").onsuccess = function (arr) {
arr.forEach(function (l) { // todo });
}
分页
context.log.page(1, 10).onsuccess = function (arr, count) {
arr.forEach(function (l) { // todo });
}
//在controller对应的action中
scope.page(1, 10).onsuccess = function (arr, count) {
arr.forEach(function (l) { // todo });
}
总条数
context.log.count().onsuccess = function (count) {
// todo
}
//在controller对应的action中
scope.count().onsuccess = function (count) {
// todo
}
- 改
context.log.default(l => l.date === "201712").onsuccess = function (result) {
if (result === null)
;// todo
else {
result.remark = "remark";
result.update();
}
}
context.log.where(l => l.title === "Login").onsuccess = function (arr) {
arr.forEach(function (l) {
l.remark = "login";
l.update();
});
}
//在controller对应的action中
scope.default(l => l.date === "201712").onsuccess = function (result) {
if (result === null)
;// todo
else {
result.remark = "remark";
result.update();
}
}
scope.where(l => l.title === "Login").onsuccess = function (arr) {
arr.forEach(function (l) {
l.remark = "login";
l.update();
});
}
- 删
context.log.default(l => l.date === "201712").onsuccess = function (result) {
if (result === null)
;// todo
else
result.delete();
}
context.log.where(l => l.title === "Login").onsuccess = function (arr) {
arr.forEach(function (l) {
l.delete();
});
}
//在controller对应的action中
scope.default(l => l.date === "201712").onsuccess = function (result) {
if (result === null)
;// todo
else
result.delete();
}
scope.where(l => l.title === "Login").onsuccess = function (arr) {
arr.forEach(function (l) {
l.delete();
});
}
身份验证
action中
scope.Auth.User //String
scope.Auth.Role //String
scope.Auth.set //Function arg: user, role, expiredays;
scope.Auth.clear //Function
重定向
action中
scope.redirect //Function arg: url;
等待异步处理完成
action中
setTimeout(function () {
scope.date = Date.now();
scope.async();
}, 1000);
context.user.default(u => u.uid === scope.query.uid).onsuccess = function (resault) {
if (resault === null) {
scope.msg = {rc: 1, rm: "用户不存在"};
scope.async();
} else
scope.async({rc: 0, rm: "用户已存在"});
};
return false;//异步标志,任务被挂起,直到scope.async被执行。