- 浏览: 265782 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
DragonKiiiiiiiing:
支持楼主,中国互联网太缺这种无私奉献的人了。您的这本书我已拜读 ...
JAVA NIO 全书 译稿 -
sp42:
非常感谢!热部署帮助很大!
Pure JS (2): 热部署 (利用 JDK 7 NIO 监控文件变化) -
sp42:
其实在我的架构中,我更倾向于 JSP 作为前端模板系统~还是写 ...
Pure JS (5.3):pure.render 的实现(构造window对象,实现服务器端 JQuery Template) -
sp42:
非常不错,楼主做的正是鄙人想做的做的,而且比鄙人的来的成熟、健 ...
OMToolkit介绍(5): 总结 -
cfanllm:
楼主辛苦了,,,谢谢分享啊
JAVA NIO 全书 译稿
PandaJS 使用说明(1.5):页面渲染与数据库操作
PandaJS 在服务器端的页面渲染也采用 JQuery Template 的语法,而数据库操作接口的语法与 Mongo Shell 上直接执行的原生语法非常接近。这使得我们可以在服务器端和客户端共用页面渲染代码,并且可以直接使用从前端传递过来的 JavaScript 对象与数据库进行交互。
不过,对客户端提交的数据进行校验也是必要的,这部分代码也可以在服务器端和客户端之间共用,这个话题将在后面的文章中提及,这里暂不考虑。
运行效果
代码编写完成后,可以启动应用并输入 http://localhost 访问页面。
界面如下图所示:
这个例子非常简单,只包括一个 users 列表,对每条数据可以执行两个操作:
1. 修改 description,并点击 Save 进行保存
2. 点击 Delete 删除对应的 user
最后一行用于增加 user ,可以执行两个操作:
1. 输入 name 和 description,并点击 Save 增加记录
2. 点击 Clear ,清空 name 和 description ,重新输入
第一次请求返回的是已经在服务器端渲染过的页面,而更新 users 列表后将会使用客户端 JS 重新渲染界面。
包含页面模板的 HTML
以下是包含模板的 html 文件,也就是后续需要进行操作的文件(webapp/index.html):
<html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <link href="css/index.css" rel="stylesheet" type="text/css" /> <title>DBO Example</title> </head> <body> <div align="center"> <h1>DBO Example</h1> <div id="error"> </div> <table id="content"> </table> </div> <script id="content-tmpl" type="tmpl"> <tr align="left"> <th class="w100">User</th> <th class="w150">Description</th> <th class="w100" colspan="2">Operation</th> </tr> <tr align="left"> <td> <input class="w90"/> </td> <td> <input class="w140" /> </td> <td> <a href="##">Save</a> </td> <td> <a href="##">Clear</a> </td> </tr> </script> <script id="user-tmpl" type="tmpl"> <tr align="left"> <td> ${name} </td> <td> <input class="w140" value="${desc}" /> </td> <td> <a href="##">Save</a> </td> <td> <a href="##">Delete</a> </td> </tr> </script> <script src="js/lib/jquery.js"> </script> <script src="js/lib/jquery.tmpl.js"> </script> <script src="js/lib/json.js"> </script> <script src="js/lib/panda.js"> </script> <script src="js/both/views.js"> </script> <script src="js/index.js"> </script> </body> </html>
【content-tmpl】:包含表格的列标题和最后一行(用于增加 user )。
【user-tmpl】:表格的一行,包含 user 数据。
需要注意的是,内容为空的 div、table、script 元素中都增加了空格,这是因为服务器端渲染的序列化实际上使用的是 JAVA XML DOM 操作,会将这些内容为空的元素的起始标记和结束标记合并,如合并为 "<div />"、"<table />"、"<script />",这在浏览器中显示时会带来一些问题。
页面渲染代码
在 webapp/js/both/views.js 中,我们可以看到如下代码:
// @include "../../../scripts/spket.js" var views = {}; views.index = function($, users) { var content = $("#content-tmpl").tmpl(), rows = $("#user-tmpl").tmpl(users); $("#content").html(content); $("#content tr:first").after(rows); $("#error").hide(); };
这里实现了 views.index(...) 方法,接收两个参数:jQuery 对象和 users 数据,然后完成对页面的渲染。
客户端 JS
客户端与该页面对应的 JS 文件是 webapp/js/index.js :
// @include "../../scripts/spket.js" $(function(){ bind(); // 绑定事件 function bind() { var rows = $("#content tr:not(:last) a"), last= $("#content tr:last a"); rows.filter(":even").click(update); rows.filter(":odd").click(remove); last.eq(0).click(add); last.eq(1).click(clear); } // 修改 user function update() { var $tr = $(this).parent().parent(), name = $tr.find("td:first").html().trim(), desc = $tr.find("input").val(); save("users.update", { name: name, desc: desc }); } // 删除 user function remove() { var $tr = $(this).parent().parent(), name = $tr.find("td:first").html().trim(); var req = { action: "users.remove", params: name }; panda.post(req, show); } // 增加 user function add() { var $input = $(this).parent().parent().find("input"), name = $input.eq(0).val(), desc = $input.eq(1).val(); save("users.add", { name: name, desc: desc }); } // 清空输入 function clear() { var $input = $(this).parent().parent().find("input"); $input.val("").eq(0).focus(); } // 在修改或增加 user 时调用 // 发送请求到服务器端,返回后渲染页面 function save(action, user) { var req = { action: action, params: user }; panda.post(req, show); } // 每次修改数据时重新渲染页面、绑定事件 function show(users) { views.index($, users); bind(); } });
服务器端 JS (DBO)
数据库相关的服务器端 JS 位于 scripts/app/dbo/users.js。
它将根据获得的参数,对 MongoDB 的 conllection 进行操作 。
dbo.users 对象实现了以下四个方法:
1. list :获取 users 列表;当 users 为空时,进行数据初始化
2. add:创建 user,返回 users 列表
3. update:更新 user,以 name 作为查询条件,更新特定的 user ,返回 users 列表
4. remove : 删除 user,以 name 作为查询条件移除特定的 user ,返回 users 列表
// @include "../../../scripts/spket.js" dbo.users = function(){ var users = panda.db.get("users"); return { list: function() { if (!users.count()) { init(); } return users.list().$sort({ name: 1 }); }, add: function(user) { users.insert(user); return this.list(); }, update: function(user) { var q = { name: user.name }; users.update(q, user, true, false); return this.list(); }, remove: function(name) { users.remove({ name: name }); return this.list(); } }; function init() { panda.db.eval(function(){ var users = db.users; users.drop(); users.ensureIndex({ name: 1 }, { unique: true }); users.insert({ name: "user1", desc: "desc1" }); users.insert({ name: "user2", desc: "desc2" }); users.insert({ name: "user3", desc: "desc3" }); }); } }();
服务器端 JS (PAGE)
页面请求默认映射到 page.index,url 格式为 http://baseURL/method/params[0]/params[1]/...
baseURL 这里对应的是 localhost,method 这里对应的是 index (省略),method 之后的参数以 "/" 分隔,作为 params 数组;
也可以结合传统的传参方式: http://baseURL/method/params[0]/params[1]?a=xxx&b=yyy,
然后用 req,getParameter(...) 获取参数。
服务器端页面渲染 JS 位于 scripts/app/page/index.js:
// @include "../../../scripts/spket.js" page.index = function(params, req, res) { return panda.render("index", function($){ views.index($, dbo.users.list()); }); };
通过 dbo.users.list() 获取 users 列表,并在 panda.render 的回调函数中调用公共的页面渲染函数进行界面渲染。
服务器端 JS (API)
供客户端 JS 调用的服务器端 API 的实现位于 scripts/app/api/users.js:
// @include "../../../scripts/spket.js" api.users = { add: function(params, req, res) { return dbo.users.add(params); }, update: function(params, req, res) { return dbo.users.update(params); }, remove: function(params, req, res) { return dbo.users.remove(params); } };
页面渲染 API 简述
页面渲染 API 的使用可以参考 scripts/test/lib/render 中的测试案例(通过 scripts/test/lib/render.js 运行) 。
首先,PandaJS 在服务器端提供对 jQuery 和 jQuery Template 语法的支持,但不包括 data 和 event。
请参考:
http://api.jquery.com/
http://api.jquery.com/category/plugins/templates/
这里不再重复说明。
下面以子页面的组装为例进行说明。
我们可以用两种方式实现页面组装:
方式一:
1.对子页面进行渲染,渲染目标为一个临时的 div,渲染完成后将 body 的内容替换为这个临时的div。
2.将子页面渲染结果插入到父页面中的指定位置
var htmlData = { htmlBody: "<b>HTML</b>" }, textData = { textBody: "Text" }; // 第一个参数为 true 表示渲染为子页面,不加入 doctype 等 var childHtml = pure.render(true, "child", function($) { var $html = $("#child-html-tmpl" ).tmpl(htmlData), $text = $("#child-text-tmpl" ).tmpl(textData) var $target = $("#target").append($html).append($text); $("body").html($target.html()); }); return pure.render("test", function($) { $("#b").append(childHtml); });
输入:
test.html
<div id="a" name="pre-middle-aend" words="word xxx"> <div id="b" name="pre" words="xxxx word" class="clz"> <h1 id="h1">John</h1> </div> </div>
child.html
<div id="target"></div> <script id="child-html-tmpl" type="text/x-jquery-tmpl"> <p>{{html htmlBody}}</p> </script> <script id="child-text-tmpl" type="text/x-jquery-tmpl"> <p><b>${textBody}</b></p> </script>
输出:
<DIV id="a" name="pre-middle-aend" words="word xxx"> <DIV class="clz" id="b" name="pre" words="xxxx word"> <H1 id="h1">John</H1> <P><B>HTML</B></P> <P><B>Text</B></P> </DIV> </DIV>
方式二:
1.将子页面的模板添加到父页面中
2.在父页面中统一进行渲染
var htmlData = { htmlBody: "<b>HTML</b>" }, textData = { textBody: "Text" }; var childTmpl = pure.render(true, "child-tmpl"); context.html = pure.render("test", function($) { $("body").append(childTmpl); var $html = $("#child-html-tmpl" ).tmpl(htmlData), $text = $("#child-text-tmpl" ).tmpl(textData) $("#b").append($html).append($text); });
输入:
test.html (同上,略)
child-tmpl.html
<script id="child-html-tmpl" type="text/x-jquery-tmpl"> <p>{{html htmlBody}}</p> </script> <script id="child-text-tmpl" type="text/x-jquery-tmpl"> <p><b>${textBody}</b></p> </script>
输出:(同上,略)
数据库操作 API 简述
页面渲染 API 的使用可以参考 scripts/test/lib/db 中的测试案例(通过 scripts/test/lib/db.js 运行) 。
这里选择其中的几个重要的 API 进行介绍。
【通过 eval 进行数据的初始化】
数据初始化的脚本 before.js 调用 pure.db.eval(func) 进行数据的初始化,传入一个函数,函数中的代码将直接在 MongoDB 运行,可以在这里查看原生的 MongoDB js 的写法:
http://www.mongodb.org/display/DOCS/SQL+to+Mongo+Mapping+Chart
pure.db.eval(function(){ var users = db.users; users.ensureIndex({ name: 1 }); users.insert({ name: "user1", desc: "desc1" }); users.insert({ name: "user2", desc: "desc2" }); users.insert({ name: "user3", desc: "desc3" }); });虽然 eval 很酷,但根据官方文档说明,运行 eval 时将阻塞所有的其他操作。
因此,最好只在数据初始化、数据迁移等特殊应用场景使用它。
【list (find)】
list 是我根据自己的习惯为 MongoDB 原生 JS 中的 find 方法起的一个别名,仍然使用find也是可以的。
list 函数名前带上 “$” 表示将结果转换为 JavaScript 数组,否则将继续保留 DBCursor 形式,以便进行排序等后续操作。
// 通过 pure.db.get 获取名为 "users" 的 collection var users = pure.db.get("users"), // 获取所有 user listAll = users.$list(), // 获取第 2-4 个 user listWithLimit = users.list().skip(1).$limit(2), // 获取 name 大于 "user1",小于 "user3" (按字典序)的 user listWithCompare = users.$list({ name:{ $gt:"user1", $lt:"user3" } }), // 获取 name 等于 "user1",或者 desc 等于 "desc2" 的 user listWithOr = users.$list({ $or:[{ name:"user1"}, {desc:"desc2"} ] }), // 获取所有 user,并按 desc 升序排列 listWithOrder = users.list().$sort({ desc: 1 }), // 获取所有 user,并按 desc 排除重复,保持 desc 唯一性 listWithDistinct = users.distinct("desc"), // 只获取 desc 字段,并且按 desc 升序排列 // 第一个参数,也就是条件参数为空, 表示不进行过滤,获取所有记录 listSomeField = users.$list({}, { desc:1 }), // 用正则表达式进行获取,获取 name 中包含 "user" 的 user listWithLike = users.$list({ name: /user/ }), // 获取存在 "age" 属性的 user listWithExists = users.$list({ age: { $exists: true } });
【insert,update,remove】
使用 insert 插入数据,update 更新数据,remove 删除数据;也可以使用 save 插入或更新数据。
// 插入 name 为 "user4", desc 为 "desc4" 的 user users.insert({ name: "user4", desc: "desc4" }); // 更新 name 为 "user1" 的 user var query = { name: "user1" }; users.update(query, { $set: { desc: "new desc" } }); // 更新 name 包含 "user" 的所有 user // 第三个参数表示是否在记录不存在的情况下插入一条记录 // 第四个参数表示批量更新 var query = { name: /user/ }; users.update(query, { $set: { desc: "new desc" } }, false, true); // 删除 name 为 "user1" 的 user users.remove({ name: "user1" });
关于 upate 的更多用法,可以参考这里:
http://www.mongodb.org/display/DOCS/Updating
- HelloPanda.zip (3.8 MB)
- 下载次数: 20
发表评论
-
PandaJS: Rhino + MongoDB + Server-side JQuery Template
2011-09-22 12:36 2170PandaJS: Rhino + MongoDB + Serv ... -
PandaJS: Rhino + MongoDB + Server-side JQuery Template
2011-09-22 12:29 0PandaJS: Rhino + MongoDB + Serv ... -
PandaJS 使用说明(1.10):小结
2011-09-01 07:45 1823PandaJS 使用说明(1.10):小结 PandaJS ... -
PandaJS 使用说明(1.9):编写测试
2011-08-31 08:13 1327PandaJS 使用说明(1.9):编写测试 Panada ... -
PandaJS 使用说明(1.8):配置文件
2011-08-29 07:48 1310PandaJS 使用说明(1.8):配置文件 配置文件的 ... -
PandaJS 使用说明(1.7):权限控制和数据校验
2011-08-28 11:57 1682PandaJS 使用说明(1.7):权 ... -
PandaJS 使用说明(1.6):日志与 proxy 对象
2011-08-27 13:52 1825PandaJS 使用说明(1.6):日 ... -
PandaJS 使用说明(1.4):配置 Spket 智能感知
2011-08-23 07:46 1903PandaJS 使用说明(1.4):配置 Spket 智能感知 ... -
PandaJS 使用说明 (1.3): 文件上传与下载
2011-08-22 09:51 2218PandaJS 使用说明 (1.3): 文件上传与下载 P ... -
PandaJS 使用说明 (1.2): Hello, World!
2011-08-20 08:41 2320PandaJS 使用说明 (1.2): Hello, Worl ... -
PandaJS 使用说明 (1.1):运行、调试、测试、部署
2011-08-18 07:44 2560PandaJS 使用说明 (1.1): ...
相关推荐
你将学习如何创建和配置表单,以及如何将表单与数据库操作结合,实现数据的编辑功能。 视图(View)是MVC模式中的一个重要部分,负责呈现应用程序的用户界面。在 Zend Framework 中,视图脚本通常用 PHP 编写,但...
**VRay Adv 1.5 RC5 渲染器** 是一个专为 **3ds Max** 设计的高级渲染插件,它提供了强大的光能传递技术,为用户在3D建模与渲染过程中提供高质量的图像输出。这个版本是无任何功能限制的,意味着用户可以充分利用其...
VRay Adv 1.5 RC5 渲染器,是一款在 3ds max 上的高级光能传递渲染插件,无任何限制的版本。本 VRay版本支持 3dsmax9 32bit/64bit 版本。 【安装及使用方法】 使用方法: 1.在安装前必须卸载先前安装过的 Vray 英文...
**八、安装与使用** 安装VRay_Adv_1.5 SP2.exe文件,即可在3Dmax中集成VRay 1.5插件。在3Dmax中,用户可以通过插件界面设置渲染参数,创建和编辑灯光、材质,然后开始渲染过程。 总之,VRay 1.5 for 3Dmax是一款...
在这个案例中,我们关注的是VRay Adv1.5 SPMAX 2009版本,它是专门为3ds Max 2009设计的增强版渲染插件。 **VRay Adv1.5主要特性:** 1. **物理相机**:VRay提供了模拟真实摄影机功能的物理相机,包括焦距、光圈、...
VRay Adv 1.5 SP2 高级渲染器,这是一款众所周知的,运行在 3ds max 上的高级光能传递渲染插件,无水印,无任何限制的版本。本 VRay版本支持 3dsmax2009_32bit 版本。 --------------------------------------------...
### VR1.5渲染教程知识点详解 #### 一、VRay渲染器的特点与版本 - **真实性**: VRay渲染器能够提供极其逼真的渲染效果,包括但不限于照片级别的细节呈现、真实的阴影效果以及精确的材质模拟。这意味着用户可以利用...
4. **分布式渲染**:VRay 1.5 支持分布式渲染,可以利用多台计算机的处理能力加速渲染过程,尤其对于大规模项目或高分辨率图像,这是非常实用的功能。 5. **汉化版**:汉化版是为了方便中国用户使用,将软件界面和...
系统分为管理员和普通用户两种角色。...使用themeleaf进行模板渲染 ## 运行步骤 第一步:sql导入mysql数据库 .sql 第二步:导入项目 第三步:配置jdk环境 第四步:配置maven环境 第五步:配置你得数据库
max 2009高级渲染器 VR1.5简体中文版
Vray1.5RC3是3Dmax的一款高级渲染插件,主要针对3ds Max的光能传递渲染功能进行了优化和增强。这款渲染器在3ds Max 6、7...如果你正在使用或计划学习3ds Max,并希望提升渲染水平,那么Vray1.5RC3绝对值得你深入研究。
《VR1.5:3D效果图渲染利器》 在3D设计领域,VRay(V-Ray)是一款备受推崇的效果图渲染引擎,而VR1.5版本则是其历史上的一个重要里程碑。作为3ds Max的插件,VRay以其强大的渲染能力、高效的计算效率以及丰富的材质...
- 使用Servlet和JSP(JavaServer Pages)进行后端处理和页面渲染。 - MVC(Model-View-Controller)架构模式,将业务逻辑、视图和控制分离,有助于代码组织和维护。 7. **前端技术**: - HTML/CSS/JavaScript...
《VRay 1.5 RC3 渲染器汉化版详解》 在计算机图形学领域,渲染器作为核心组件,对于最终图像质量和效果起着决定性的作用。VRay,由 Chaos Group 开发,是一款广泛应用的高质量渲染软件,广泛应用于建筑设计、电影...
Servlet在Web应用中扮演着控制器的角色,它处理HTTP请求,调用业务逻辑(如数据库操作),并将结果转发给相应的JSP页面进行渲染。例如,当用户提交一个删除操作,Servlet接收请求,通过JDBC执行删除操作,然后返回...
V-Ray 1.5 RC3是该软件的一个较早版本,但仍然在许多3D艺术家和设计师中使用,特别是那些依赖3Ds Max 9或10的人。 渲染器是3D软件的核心组件,负责将3D场景转化为2D图像的过程。V-Ray渲染器以其高效的光线追踪和...
10. **兼容性**:V-Ray 1.5+SP4特别适用于3ds Max 2010版本,确保与该软件的无缝集成。 对于初学者来说,使用V-Ray可能需要一定的学习曲线,但一旦掌握,它能帮助你创造出令人惊叹的3D图像和动画。提供的VRay1.5+SP...
对于中文用户来说,汉化版的VRay 1.5 RC3消除了语言障碍,使得操作界面和帮助文档更为易懂,降低了学习和使用的难度。这对于初学者和非英语背景的专业人士尤其有利,能够更快地掌握软件功能,提升工作效率。 四、...