Ajax链接扩展
<a href=”xxx” target=“ajax” [rel=“boxId”]> 示例: <a href="w_alert.html" target="ajax" rel="container">提示窗口</a>
当前navTab中链接ajax post扩展
<a href="user.do?method=remove" target="navTabTodo">删除</a>
dialog链接扩展
<a href=”xxx” target=“dialog” [rel=“dialogId”]>
Html标签扩展方式示例:
<a href="w_dialog.html" target="dialog" rel="page2">弹出窗口</a> 或 <a class="button" href="demo_page1.html" target="dialog" rel="dlg_page1" title="[自定义标题]" width="800" height="480">打开窗口一</a>
JS调用方式示例:
$.pdialog.open(url, dlgId, title); 或 $.pdialog.open(url, dlgId, title, {width: 500, height: 300});
navTab链接扩展
<a href=”xxx” target=“navTab” [rel=“tabId”]> 示例: <a href="w_alert.html" target="navTab" rel="page1">提示窗口</a>
Tab组件扩展
开发人员不需写任何javacsript, 只要使用下面的html结构就可以.
<div class="tabs">
<div class="tabsHeader">
<div class="tabsHeaderContent">
<ul>
<li class="selected"><a href="#"><span>标题1</span></a></li>
<li><a href="#"><span>标题2</span></a></li>
</ul>
</div>
</div>
<div class="tabsContent" style="height:150px;">
<div>内容1</div>
<div>内容2</div>
</div>
<div class="tabsFooter">
<div class="tabsFooterContent"></div>
</div>
</div>容器高度自适应
容器高度自适应, 只要增加扩展属性layouth=”xx”, 单位是像素.
Layouth表示容器内工具栏高度. 浏览器窗口大小改变时容器高度自适应, 但容器内工具栏高度是固定的, 需要告诉js工具栏高度来计算出内容的高度.
示例: <div layouth=“150”>内容</div>
Table扩展
在table标签上增加class=”table”
<table layouth="170" class="table">
<thead>
<tr>
<th width="80">客户号</th>
<th width="100">客户名称</th>
<th align="right">证件号码</th>
<th width="100">建档日期</th>
</tr>
</thead>
<tbody>
<tr>
<td>iso127309</td>
<td>北京市政府</td>
<td>0-0001027766351528</td>
<td>2009-05-21</td>
</tr>
</tbody>
</table>在线编辑器
在textarea标签上增加class=”editor”
示例:
<textarea class="editor" name="description" rows="15" cols="80">内容</textarea>
Ajax表单提交
普通Ajax表单提交方式
DWZ 表单提交dwz.ajax.js
Ajax 表单提交后自动调用默认回调函数, 操作成功或失败提示.
Form标签上增加 onsubmit=”return validateCallBack(this);
Ajax 表单提交后如果需要做一些其它处理也可以自定义一个回调函数. 例如下面表单提交成功后关闭当前navTab, 或者重新载入某个tab.
Form标签上增加onsubmit=”return validateCallBack(this, navTabAjaxDone)”
/** * navTabAjaxDone是DWZ框架中预定义的表单提交回调函数. * 服务器转回navTabId可以把那个tab标记为reloadFlag=1, 次下切换到那个tab时会重新载入内容. * navTabId如果是closeCurrent就会关闭当前tab * navTabAjaxDone这个回调函数基本可以通用了,如果还有特殊需要也可以自定义回调函数. * 如果表单提交只提示操作是否成功, 就可以不指定回调函数. 框架会默认调用ajaxDone() * <form action="/userAction?method=save" onsubmit="return validateCallBack(this, navTabAjaxDone)"> * * form提交后返回json数据结构statusCode=200表示操作成功, 做页面跳转等操作. statusCode=300表示操作失败, 提示错误原因. * {"statusCode":"200", "message":"操作成功", "navTabId":"navNewsLi", "forwardUrl":"", "callbackType":"closeCurrent"} * {"statusCode":"300", "message":"操作失败"} */ function navTabAjaxDone(json){ ajaxDone(json); if (json.statusCode == 200){ if (json.navTabId){ navTab.reloadFlag(json.navTabId); } else { navTabPageBreak(); } if ("closeCurrent" == json.callbackType) { navTab.closeCurrentTab(); } else if ("forward" == json.callbackType) { navTab.reload(json.fowrwardUrl); } } }
示例:
<form method="post" action="url" class="pageForm required-validate" onsubmit="return validateCallBack(this);">
<div class="pageFormContent" layoutH="56">
<p>
<label>E-Mail:</label>
<input class="required email" name="email" type="text" size="30" />
</p>
<p>
<label>客户名称:</label>
<input class="required" name="name" type="text" size="30" />
</p>
</div>
<div class="formBar">
<ul>
<li>
<div class="buttonActive"><div class="buttonContent"><button type="submit">保存</button></div></div>
</li>
<li>
<div class="button"><div class="buttonContent"><button type="Button" onclick="navTab.closeCurrentTab()">取消</button></div></div>
</li>
</ul>
</div>
</form>文件上传表单提交方式
因为Ajax不支持enctype=”multipart/form-data” 所以用隐藏iframe来处理无刷新表单提交.
<form method="post" action="url" class="pageForm required-validate" enctype="multipart/form-data" onsubmit="return ifarmeCallback(this);"> 或 <form method="post" action="url" class="pageForm required-validate" enctype="multipart/form-data" onsubmit="return ifarmeCallback(this, xxxCallback);">
服务器端需要返回
<script type="text/javascript"> var statusCode="${statusCode}"; var message="${message}"; var navTabId="${navTabId}"; var response = {statusCode:statusCode, message:message, navTabId:navTabId } if(window.parent.donecallback) window.parent.donecallback(response); </script>
Java服务器端表单处理示例
public class UserAction extends BaseAction { public ActionForward changePwd(ActionMapping mapping, BaseActionForm bForm, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { UserForm form = (UserForm) bForm; if (form.getOldPassword() == null || "".equals(form.getOldPassword().trim())) { request.setAttribute("statusCode", 300); request.setAttribute("message", this.getMessage(request, "msg.oldpassword.invalid")); return mapping.findForward("done"); } User user = AppContextHolder.getContext().getUser(); try { UserManager uManager = BusinessFactory.getFactory() .getUserManager(); uManager.changePassword(user, form.getOldPassword(), form .getPassword()); request.setAttribute("statusCode", 200); request.setAttribute("message", this.getMessage(request, "msg.operation.success")); } catch (PasswordNotCorrectException e) { request.setAttribute("statusCode", 300); request.setAttribute("message", this.getMessage(request, "msg.password.incorrect")); } return mapping.findForward("done"); } protected ActionForward callbackForward(ActionMapping mapping, HttpServletRequest request) { if (ServerInfo.isAjax(request)) return mapping.findForward("done"); return mapping.findForward("callbackDone"); } } public class ServerInfo { public static boolean isAjax(HttpServletRequest request) { if (request != null && "XMLHttpRequest".equalsIgnoreCase(request .getHeader("X-Requested-With"))) return true; return false; } }
DWZ js库介绍
DWZ框架初始化
在<head>引入必要的js库
DWZ框架初始化会自动读取dwz.frag.xml中的页面组件碎片代码.
dwz.frag.xml中定义了一些dwz组件碎片和提示信息, 需要初始化到DWZ环境中.
注意dwz.frag.xml路径问题.
假设dwz.frag.xml放在根目录下, 在<head>标签中调用DWZ.init(“dwz.frag.xml”)
<script type="text/javascript"> $(function(){ DWZ.init("dwz.frag.xml", function(){ initEnv(); $("#themeList").theme({themeBase:"themes"}); }); }) </script>
dwz.core.js
DWZ核心库主要功能是DWZ初始化, Javascript String增加了一些扩展方法.
dwz.ajax.js
ajax表单提交封装
dwz.alertMsg.js
Ø 确认提示框
alertMsg.confirm("您修改的资料未保存,请选择保存或取消!", { okCall: function(){ $.post(url, {accountId: accountId}, ajaxDone, "json"); } });
Ø 成功提示框 alertMsg.correct(‘您的数据提交成功!’)
Ø 错误提示框 alertMsg.error(‘您提交的数据有误,请检查后重新提交!’)
Ø 警告提示框 alertMsg.warn(‘您提交的数据有误,请检查后重新提交!’)
Ø 信息提示框 alertMsg.info(‘您提交的数据有误,请检查后重新提交!’)
dwz.jDialog.js
弹出层组件
dwz.barDrag.js
DWZ左边的活动面板
dwz.navTab.js
导航tab组件
dwz.scrollCenter.js
页面容器自动居中组件
dwz.stable.js
table组件
dwz.tree.js
tree组件
dwz.theme.js
切换界面主题风格
dwz.ui.js
页面效果初始化
dwz.validate.method.js
这是jquery.validate.js表单验证扩展方法
dwz.validate.zh.js
表单验证本地化
dwz.contextmenu.js
自定义鼠标右键菜单
示例:
$("body").contextMenu('navTabCM', { bindings:{ closeCurrent:function(t){ // TODO }, closeOther:function(t){ // TODO }, closeAll:function(t){ // TODO } }, ctrSub:function(m){ var mCur = m.find("[rel='closeCurrent']"); var mOther = m.find("[rel='closeOther']"); var mAll = m.find("[rel='closeAll']"); // TODO } });
这个框架是我的好友开发,希望大家多多支持,17Joys CMS正在开发的用户中心,便建立在此开源框架的基础上。
DWZ简单介绍:
DWZ富客户端框架设计目标是简单实用, 让开发人员少写js甚至不写js的情况下, 也能用ajax做项目. 比较适合做二次开发.
DWZ使用jQuery可以非常方便的定制特定需求的UI组件, 并以jQuery插件的形式发布出来. 如有需要也可做定制化开发.
欢迎大家提出建议,我们将在下一版本中进一步调整和完善功能.
DWZ富客户端框架是开源项目,可以免费获取源码。希望更多的开发人员使用,共同推进国内整体ajax开发水平。
在线演示地址 http://dwz.duqn.com
在线文档 http://dwz.duqn.com/doc/dwz-user-guide.pdf
视频教材 http://dwz.duqn.com/doc/dwz-user-guide.swf
Google Code下载: http://code.google.com/p/dwz/
演示界面:
]]>function add(){ $role=new Model('Role');//创建一个用户分组模型 $list=$role->select();//提取用户分组数据 $this->assign('rlist',$list);//分组数据分配到视图上,为了在添加用户时选择所属分组 $this->display();//调用模板显示 } function insert(){ $user=new UserModel();//创建用户模型 if($data=$user->create()){//通过create方法获取表单数据,只有这样才能激活数据验证功能 if(false!==$user->add()){//通过add方法把数据插入到数据库中 $uid=$user->getLastInsID();//获取新增用户的编号,限于自动增长列 $ru['role_id']=$_POST['role_id'];//获取选择的用户分组 $ru['user_id']=$uid;//整合用户分组明细 $roleuser=new Model('RoleUser');//创建用户分组明细模型 $roleuser->add($ru);//添加用户分组明细信息 $this->assign('jumpUrl',__URL__.'/index');//设定调整页面 $this->success('操作成功,插入数据编号为:'.$uid);//成功页面提示信息 }else{ $this->error('操作失败:adduser'.$user->getDbError());//插入错误提示 } }else{ $this->error('操作失败:数据验证( '.$user->getError().' )');//getError方法获取数据验证失败信息 } }
视图文件就是创建一个表单即可,视图文件Tpl/default/User/add.html
<form action="__URL__/insert" method="post">
<table class="admintable" id="admintable">
<tr>
<td class="key">用户名:<span class="red_font">*</span></td><td><input type="text" name="username" class="inputbox" /></td>
</tr>
<tr>
<td class="key">密码:<span class="red_font">*</span></td><td><input type="password" name="pwd" class="inputbox" /></td>
</tr>
<tr>
<td class="key">昵称:<span class="red_font">*</span></td><td><input type="text" name="name" class="inputbox" /></td>
</tr>
<tr>
<td class="key">邮箱:<span class="red_font">*</span></td><td><input type="text" name="email" class="inputbox" /></td>
</tr>
<tr>
<td class="key">是否激活:<span class="red_font">*</span></td>
<td>
是<input type="radio" name="active" value="1" checked="checked" />
否<input type="radio" name="active" value="0" />
</td>
</tr>
<tr>
<td class="key" valign="top">用户组:<span class="red_font">*</span></td>
<td>
<select name="role_id" size="10">
<volist name="rlist" id="row">
<option value="{$row['id']}">{$row['name']}</option>
</volist>
</select>
</td>
</tr>
<tr>
<td>
<input class="button" type="submit" value="保存" />
<input class="button" type="submit" value="应用" />
<input class="button" type="button" onclick="history.go(-1);" value="取消" />
</td>
</tr>
</table>
</form>以上就是添加用户操作,注意action要连接到inser操作上,表单中字段属性要与数据库字段一致,或者与模型中的映射字段一致。
]]>ThinkPHP采用模块和操作的方式来执行,首先,用户的请求会通过入口文件生成一个应用实例,应用控制器(我们称之为核心控制器)会管理整个用户执行的过程,并负责模块的调度和操作的执行,并且在最后销毁该应用实例。任何一个WEB行为都可以认为是一个模块的某个操作,系统会根据当前的URL来分析要执行的模块和操作。这个分析工作由URL调度器来实现,官方内置了Dispatcher类来完成该调度。
在Dispatcher调度器中,会根据URL:http://servername/appName/moduleName/actionName/params
来获取当前需要执行的项目(appName)、模块(moduleName)和操作(actionName),在某些情况下,appName可以不需要(通常是网站的首页,因为项目名称可以在入口文件中指定,这种情况下,appName就会被入口文件替代)。在复杂一点的情况下面,可能还会出现分组(groupName)。
每个模块是一个Action文件,类似于我们平常所说的控制器,系统会自动寻找项目类库Action目录下面的相关类,如果没有找到,则会定位到空模块,否则抛出异常。
而actionName操作是首先判断是否存在Action类的公共方法,如果不存在则会继续寻找父类中的方法,如果依然不存在,就会寻找是否存在自动匹配的模版文件。如果存在模版文件,那么就直接渲染模版输出。
因此应用开发中的一个重要过程就是给不同的模块定义具体的操作。一个应用如果不需要和数据库交互的时候可以不需要定义模型类,但是必须定义Action控制器。
Action控制器的定义非常简单,只要继承Action基础类就可以了,例如:
class UserAction extends Action{
}
如果我们要执行下面的URL
http://servername/index.php/User/add
你需要增加一个add方法就可以了,例如
Class UserAction extends Action{ // 定义一个add操作方法,注意操作方法不需要任何参数 Public function add(){ // add操作方法的逻辑实现 // …… $this->display(); // 输出模板页面 } }
操作方法必须定义为Public类型,否则会报错。并注意操作方法的命名不要和内置的Action类的方法重复。系统会自动定位当前操作的模板文件,而默认的模板文件应该位于项目目录下面的Tpl\default\User\add.html。
17JoysCMS用户管理功能需要的操作就是:用户列表、创建用户、编辑用户、删除用户、插入用户数据、更新用户数据
所以控制器的结构如下
class UserAction extends CommonAction{ /* 用户列表 */ funciton index(){ } /* 添加用户 */ funciton add(){ } /* 编辑用户 */ funciton edit(){ } /* 删除用户 */ funciton delete(){ } /* 插入用户数据 */ funciton insert(){ } /* 更新用户数据 */ funciton update(){ } }
此文件保存于Action/UserAction.class.php文件中
]]>开发目的:为了让跟多的PHP爱好者掌握ThinkPHP框架开发,我们提供CMS源码作为教学案例,希望更多的PHP爱好者可以掌握,并且参与到我们17Joys CMS的开发团队中来
环境要求:php5+mysql5
功能及模块:
1,单元、分类、文章内容管理,可自定义开发内容组件,前台动态分配
2,菜单、菜单项管理,灵活的内容分配,可以指定菜单项绑定的内容,并支持无限级菜单项
3,模块管理,自定义开发内容模块:支持任意表现形式,菜单、最新文章、相关文章等。
4,用户、用户分组管理,强大的RBAC用户认证机制
5、支持SEO伪静态,内容缓存能提高程序执行速度
6、程序模板分离可以制作自己喜欢的网站且不需懂程序
安装方式:http://youdomain/Install/index.php
官方网站:http://www.17joys.com
17Joys开发教学网站:http://www.17joys.com/php
支持论坛:http://www.17joys.com/bbs
项目地址:http://code.google.com/p/17joys/
SVN地址:http://17joys.googlecode.com/svn/trunk/
首页缩略图
]]>代码下载:另存为下载
页面效果图:
首页代码:Admin/Tpl/default/Index/index.html
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>管理后台</title>
</head>
<frameset rows="64,*" frameborder="NO" border="0" framespacing="0">
<frame src="__ROOT__/admin.php/Public/top" noresize="noresize" frameborder="NO" name="topFrame" scrolling="no" marginwidth="0" marginheight="0" target="main" />
<frameset cols="200,*" rows="560,*" id="frame">
<frame src="__ROOT__/admin.php/Public/left" name="leftFrame" noresize="noresize" marginwidth="0" marginheight="0" frameborder="0" scrolling="no" target="main" />
<frame src="__ROOT__/admin.php/Public/main" name="main" marginwidth="0" marginheight="0" frameborder="0" scrolling="auto" target="_self" />
</frameset>
<noframes>
<body></body>
</noframes>
</html> 这CURD操作的任务就要交给模型来完成了,在ThinkPHP中基础的模型类就是Model类,该类完成了基本的CURD、ActiveRecord模式、连贯操作和统计查询,一些高级特性被封装到另外的模型类中,例如AdvModel高级模型类完成了一些包括文本字段、只读字段、序列化字段、乐观锁、多数据库连接等模型的高级特性,ViewModel视图模型类完成了模型的视图操作,RelationModel关联模型类完成了模型的关联操作。
基础模型类Model的设计非常灵活,甚至可以无需进行任何模型定义,就可以进行相关数据表的ORM和CURD操作,只有在需要封装单独的业务逻辑的时候,模型类才是必须被定义的。
下面就上正菜,用户模型类UserModel,这个类文件放在Lib/Model目录下,命名为UserModel.class.php,说到命名就要遵循规范,ThinkPHP要求数据库的表名和模型类的命名遵循一定的规范,首先数据库的表名和字段全部采用小写形式,模型类的命名规则是除去表前缀的数据表名称,并且首字母大写,然后加上模型类的后缀定义。
例如:UserModel 表示User数据对象,由于我之前项目配置的数据库的表前缀是 joys_,所以UserModel模型其对应的数据表应该是joys_user
【注】:表设计请看17joys网站后台功能设计-阶段1
当然如果你的规则和系统的约定不符合,也可以设置Model类的tableName属性进行自定义。
下面就是我的UserModel类代码
<?php /* * 功能:用户模型类 * 作者:马明 * 版本:1.0 * 开发时间:2010.1 */ class UserModel extends Model { /* * 表单验证 */ protected $_validate = array( //array(验证字段,验证规则,错误提示,验证条件,附加规则,验证时间) array('username','require','账号名必须存在!',1,'regex',3), array('username','','账号名已经存在!',1,'unique',1), array('rpwd','pwd','两次密码不一致!',0,'confirm'), array('name','require','用户名称必须存在!',1), array('email','require','邮箱不能为空!'), //array('email','','邮箱已经存在!',1,'unique',3), array('email','checkEmail','邮箱已经存在!',1,'callback',3), array('active',array(0,1),'启用:1 ; 停用:0',0,'in'), ); /* * 字段映射 */ protected $_map=array( //'uname'=>'username', 'pwd'=>'password', ); /* * 自动填充 */ protected $_auto=array( //array(填充字段,填充内容,填充条件,附加规则) array('password','md5',1,'function'), array('reg_date','getDate',1,'callback'), array('active','1'), ); function getDate(){ return date('Y-m-d H:i:s'); } function checkEmail(){ $user=new Model('User'); if(empty($_POST['id'])){ if($user->getByEmail($_POST['email'])){ return false; }else{ return true; } }else{ if($user->where("id!={$_POST['id']} and email='{$_POST['email']}'")->find()){ return false; }else{ return true; } } } } ?>
关于这个类文件的说明,稍后我会分开给大家讲解。
]]> ThinkPHP的视图主要由View视图类和模板文件构成。视图类负责Action控制器类和模板文件之间沟通,Action类把数据通过View类传递到模板文件,而模板文件把接收到的数据转换成相应的数据格式显示。
【注】:视图仅仅是进行数据的输出显示,通常在视图渲染过程是不会改变数据本身的,而只是进行格式化输出和显示。
ThinkPHP内置了一个基于XML的性能卓越的模板引擎 ThinkTemplate,这是一个专门为ThinkPHP服务的内置模板引擎,无论在功能或是性能还有易用性方面都比Smarty优秀。这是ThinkPHP手册的原话,在我使用了一段时间后,发现还是有些小bug存在的,不过倒是无伤大雅,还是很不错的模板引擎,17joys决定就采用ThinkPHP提供的这款模板引擎进行开发,如果习惯Smarty模板引擎的同学,也可以很容易的更换,稍后我会把配置使用Smarty的方法发布出来。
下面开始创建模板,模板目录默认是项目下面的Tpl, 模板主题默认是default,模板主题功能是为了多模板切换而设计的,如果有多个模板主题的话,可以用TMPL_DEFAULT_THEME参数设置默认的模板主题名。以后我们可以很方便的定义前台模板主题了。
为了对模板文件更加有效的管理,ThinkPHP对模板文件进行目录划分,默认的模板文件定义规则是:
模板目录/模板主题/[分组名/]模块名/操作名+模板后缀
那针对Index模块的index操作,我们的模板存放路径:Tpl/default/Index/index.html
换做User模块的add操作,模板存放路径:Tpl/default/User/add.html
当然后台代码就不需要向前台那么复杂了,一般我们都会考虑使用分帧的框架搭建,不过17joys采用的是纯AJAX后台,为了AJAX的调用和更新页面的考虑,所以页面使用的是DIV+CSS布局。
<body scroll="no"> <div id="layout"> <div id="header"> <div class="headerNav"> <a class="logo" href="#">17joyslogo</a> <ul class="nav"> <li><a href="#">切换角色</a></li> <li><a href="#">设置</a></li> <li><a href="#">反馈</a></li> <li><a href="#">帮助</a></li> <li><a href="#">退出</a></li> </ul> <ul class="themeList" id="themeList"> <li class="t1" theme="default"><div class="selected">蓝色</div></li> <li class="t2" theme="green"><div>绿色</div></li> <li class="t3" theme="red"><div>红色</div></li> <li class="t4" theme="purple"><div>紫色</div></li> <li class="t5" theme="silver"><div>银色</div></li> </ul> </div> </div> <div id="leftside"> <div id="sidebar_s" style="display:none;"> <div class="collapse"> <div class="toggleCollapse"><div>d</div></div> </div> </div> <div id="sidebar"> <div class="toggleCollapse"><h2>主菜单</h2><div>收缩</div></div> <div class="accordion"> <div class="accordionHeader"> <h2><span>Folder</span>网站管理</h2> </div> <div class="accordionContent" style="display:block;"> <ul class="tree treeFolder"> <li><a href="tabsPage.html" target="navTab">控制面板</a> <ul> <li><a href="main.html">我的主页</a></li> </ul> </li> <li><a href="w_form.html" target="navTab" rel="joys_menu">菜单</a> <ul> <li><a href="w_button.html">菜单管理</a></li> </ul> </li> </ul> </div> <div class="accordionHeader"> <h2><span>Folder</span>会员管理</h2> </div> <div class="accordionContent" style="display:block;"> <ul class="tree treeFolder"> <li><a href="tabsPage.html" target="navTab">会员管理</a> <ul> <li><a href="">会员资料管理</a></li> <li><a href="">添加会员</a></li> </ul> </li> </ul> </div> </div> </div> </div> <div id="container"> <div id="navTab" class="tabsPage"> <div class="tabsPageHeader"> <div class="tabsPageHeaderContent"> <ul class="navTab-tab"> <li tabid="main" class="main"><a href="#"><span><span class="home_icon">我的主页</span></span></a></li> </ul> </div> <div class="tabsLeft">left</div> <div class="tabsRight">right</div> <div class="tabsMore">more</div> </div> <ul class="tabsMoreList"> <li><a href="#">我的主页</a></li> </ul> <div class="navTab-panel tabsPageContent"> <div></div> </div> </div> </div> <div id="taskbar" style="left:0px; display:none;"> <div class="taskbarContent"> <ul style="width:50000px"></ul> </div> <div class="taskbarLeft taskbarLeftDisabled" style="display:none;">taskbarLeft</div> <div class="taskbarRight" style="display:none;">taskbarRight</div> </div> <div id="splitBar"></div> <div id="splitBarProxy"></div> </div> <div class="resizable" style=" display:;"></div> <div class="shadow" style=" display:; width:508px; top:148px; left:296px;"> <div class="shadow_h"> <div class="shadow_h_l"></div> <div class="shadow_h_r"></div> <div class="shadow_h_c"></div> </div> <div class="shadow_c"> <div class="shadow_c_l" style="height:296px;"></div> <div class="shadow_c_r" style="height:296px;"></div> <div class="shadow_c_c" style="height:296px;"></div> </div> <div class="shadow_f"> <div class="shadow_f_l"></div> <div class="shadow_f_r"></div> <div class="shadow_f_c"></div> </div> </div> <div id="alertBackground" class="alertBackground"></div> </body>
这就是HTML代码部分,CSS部分暂时还没有整理完,有兴趣的同学可以自己尝试用CSS修饰一下,当然如果做出动态菜单效果的话,还需要JavaScript的帮助。当然大家也可以自己找一个写好了的后台HTML模板,在之前的一篇文章《17joys后台代码-初步搭建》中,我提供了一些后台模板,大家可以去下载使用。
]]>CommonAction.class.php文件
<?php class CommonAction extends Action { function _initialize(){ header("Content-Type:text/html; charset=utf-8"); } } ?>
之前的IndexAction类文件修改为
<?php class IndexAction extends CommonAction { //从CommonAction继续扩展继承 public function index(){ $this->display(); } } ?>
这样以后我就可以把更多的功能方法放到CommonAction类中,譬如权限验证等操作
【注】:ThinkPHP的Action类源码
39 40 41 42 43 44 45 46 | public function __construct() { //实例化视图类 $this->view = Think::instance('View'); //控制器初始化 if(method_exists($this,'_initialize')) $this->_initialize(); } |