这是俺这几天使用thinkjs
的一些心得,由于没接触过nodejs
和异步编程,代码很ZHA,如果有误人子弟请说明。。。谢谢
首先你要对她(thinkjs)有部分的了解,什么?不太熟?请移步: http://www.thinkjs.org/doc/
数据库已知表 前缀_list
, 在 Module
目录里新建文件 ListModule.js
, 代码如下:
/**
* 学习吧列表表模块
* @author xieliang
*/
module.exports = Model(function() {
'use strict';
return {
/**
* 获取列表数据
* @param {object} options 配置参数
* @return {Promise}
*
* @description
* 1, 成功的回调参数为数组 [{},{}]
* 错误的回调参数为空数组 []
* 2, one 成功的回调参数为对象 {a:1,b:2}
* one 错误的回调参数为空对象 {}
*/
get_list_data: function(options) {
var self = this,
sql;
//合并参数
options = extend(false, {
page: 1, //分页
limit: 'all', //偏移,如果为all则为全部
order: 'id DESC', //排序
cache: false, //是否加cache
field: 'id, title, url, description, keywords', //要查的字段
where: null, //条件
one: false //是否只查一个
}, options || {});
// 查字段
sql = self.field(options.field);
//如果不是一个才查排序
if (!options.one) {
if (options.limit !== 'all') {
sql.page(options.page, options.limit);
}
sql.order(options.order);
}
//如果有附加条件
if (options.where) {
sql.where(options.where);
}
//是否开启缓存
if (options.cache) {
sql.cache(true);
}
//如果是一个则用find查单个,否则查数组
return options.one ? sql.find() : sql.select();
},
/**
* 获取单条数据
* @param {object} options 配置
* @return {Promise}
*/
get_item_data: function(options) {
options = options || {};
options.one = 1;
return this.get_list_data(options);
}
}
});
以上两个方法为获取数据,一个是获取多条支持分页,一个是获取单条,来看代码如何获取吧:(代码写在控制器里)
//根据id查单个内容
testAction: function(){
var self = this;
return D('List').get_item_data({
where: {
id: 1
}
}).then(function(data){
//data = {}
if(isEmpty(data)){
console.log('空数据');
} else {
console.log('有数据');
}
console.log(data);
});
},
是不是觉得很单调? 好吧, 来个参数多的:
//like查, 并分页
test1Action: function(){
var self = this;
return D('List').get_item_data({
isPage: 1,
page: page变量,
where: {
class_id: 123,
title: ['like', '%'+ key +'%']
},
order: 'id DESC',
limit: 20
}).then(function(data){
//这里的data为数组,如果为空则是空数组
});
},
你会不会想说这只是单个查,有时候在列表里是需要查别的表数据的,比如循环列表的每行里都有作者信息,分类信息等, 那么来看下C层吧。。。
首先我强制让自己遵循一个小约定:
return
出去then
里,即使多套一个 then
也要这样做,如:testAction: function(){
var self = this;
return D('List').get_list_data().then(function(data){
// data = []
//这里是逻辑层1,要处理得到的列表循环数组
// data.forEach()....
return data;
}).then(function(data){
//data = 列表循环数组
//这里是逻辑层2, 要处理每行的分类+用户信息
//var arr = [];
//data.forEach(function(val){
// arr.push()....
//});
//return Promise.all(arr)
//
//if(data为空则) return []
return data;
}).then(function(data){
//data = 列表循环数组, 且已经处理过分类+用户信息了
//这里是逻辑层3, 要处理一些判断,或者渲染的东东
return data;
}).then(function(data){
//data = 列表循环数组, 且已经处理过分类+用户信息了, 且处理过渲染
//这里是逻辑4,渲染模板
self.assign("list", data....)
self.assign....
return self.display();//把这个return 出去 ,以便捕获异常
});
//在除了逻辑4以为的then,如果数据为空则直接return []交给逻辑4渲染模板为空, 如果数据错误则直接return 404的一个fn
}
我应该怎么在循环里查表呢?
/**
* 内部调用列表
* @description 处理分类名, 作者, 发表时间等内容
* @param {object} options 配置
* @return {Promise}
*/
_get_list: function(options) {
var self = this;
options = options || {};
return D('Content').get_list_data(options).then(function(data) { //查分类名 + 修改url + 发布时间 + 内容
var arr = [];
var List = D("List");
//如果为空则返回空数组
if(isEmpty(data)){
return arr;
}
data.forEach(function(val) {
//查分类名
arr.push(List.get_item_data({
where: {
id: val.class_id
}
}));
//修正链接
val.uri = Url.get_detail(val.id, val.url);
//发布时间
val.add_time = Date.elapsedDate(val.add_time * 1000, 'yyyy-M-d');
//去html+截取
val.article = quickHtml(val.article);
});
//数组异步处理
return Promise.all(arr).then(function(list_data) {
data.forEach(function(val, index) { //把分类的数据叠加到主数据上
if (list_data[index]) {
val.list_name = list_data[index].title;
}
});
return data;
});
}).then(function(data) {
//查作者信息
var arr = [];
var User = D("User");
//如果为空
if(isEmpty(data)){
return arr;
}
data.forEach(function(val) {
arr.push(User.get_item_data({
where: {
id: val.add_uid
}
}));
});
//数组异步处理
return Promise.all(arr).then(function(list_data) {
data.forEach(function(val, index) {
if (list_data[index]) {
val.user_name = list_data[index].user_name;
}
});
return data;
});
}).then(function(data){
//这里是渲染模板, 如果要写成公用方法这里则删除,写在你调用之后,如:
// 公用方法名().then(function(data){});
self.assign('list', data);
return self.display();
});
},
这里循环查只是利用了数组异步处理+回调,上次听 @welefen 这种形式有个很高端的方法解决,目前俺也不会,只能这样先处理了,我相信不久将来 thinkjs
官网会出相应demo的。。。啦啦啦
此外 thinkjs
还支持base
控制器,可以把一些常用的方法定义到里面,比如错误的,私有内部查询等。。。
V层就不说了,多看看模板引擎就啥也有了。。。
大家都知道一般是通过域名访问web的,但nodejs
好像只能绑定端口(俺才书学浅),那么我们就需要一个http server
了,俺选的是nginx
。。。
首先安装nginx
, 然后修改nginx
配置文件:
server {
listen 80;//http端口
server_name new.xuexb.com;//host name
root /ssd/wwwroot/www.xuexb.com;//目录
index index.js index.html;//默认主页
if ( -f $request_filename/index.html ){//如果请求的路径下有index.html,则重写到这个文件
rewrite (.*) $1/index.html break;
}
if ( !-f $request_filename ){//如果请求的文件真实路径不存在则重写到thinkjs上
rewrite (.*) /index.js;
}
location = /index.js {//配置thinkjs
proxy_set_header Connection "";
proxy_set_header Host $http_host;
proxy_set_header X-NginX-Proxy true;
proxy_pass http://127.0.0.1:81$request_uri;//这里配置thinkjs的监听端口
proxy_redirect off;
}
}
然后把thinkjs
的端口改为已知的,比如81,然后使用提供的 sh
命令来进行后台运行服务(linux系统下),然后不出意外的话访问就会成功,这个配置感谢 @welefen,这个优势在于如果是真实路径则不启用thinkjs
作服务,更快速,也可以扩展自己的 真静态
文件了,对,思路我已经想好了,只待写了。。。_
最后感谢 thinkjs
,让前端也可以写后端(虽说写的很烂)。。。
扫码关注w3ctech微信公众号
赞,欢迎多发thinkjs相关的文章
亮神好屌,哪都能见到你。。。
我是跟着你过来的。。。
<h1>不错</h1><p>真好</p>
亮神带我飞
亮了
要求不复杂的话,nodejs 本身就能当WEB服务器,thinkjs里面把配置项port: 8360,改成port: 80,就行了,访问的时候用个http://localhost/index/index 是OK的
@老六 uncaughtexception 有什么好的处理方法?
@Doerme 用domain模块。 如果用thinkjs,框架已经帮你做了,应用里不用处理了。
共收到9条回复