Octopus系列之开发过程各个技术点
自定义了页面周期
使用唯一的一个VelocityEngine全局的静态实例,优化了小泥鳅blog中每次请求都要创建VelocityEngine实例对象,减少了对象的开销
通过UA判断请求来自的设备,从而初始化不同的模板目录,从而实现手机和PC访问展示出不同的页面效果
一次请求的生命周期
参数初始化 Page_Init:
初始化请求上下文对象
请求对象
Cookie对象
货币对象
语言对象
初始化货币执行业务逻辑并写入到客户端的Cookie中
验证用户的身份 Authenticate_User
页面预加载 Page_PreLoad:会加载一些公共的数据,比如:图片URL地址,广告图片地址...;加载语言包数据;判断Form参数个数引发Post事件
页面加载事件 Page_Load:需要留给各个子页面实现,必须实现的一个,主要在子页面中完成各自的业务处理,数据获取与填充
页面预结束事件 Page_PreEnd:暂时还没有做处理
页面结束事件 Page_End:合并模板和业务数据
this.pcMobile【判断请求时做的初始化】 + this.templateFile 【在各个子页面重写Page_Load事件时做初始化】
用户验证逻辑的实现
使用虚拟的protected virtual void Authenticate_User()来实现,这样可以被子类重写,从而可以做后台管理类的程序,比如会员中心里面的页面,需要用户登录之后才能访问
判断用户登录使用的是检查session中登陆的用户对象来实现的 同时还有关于匿名用户登陆的问题,这个在后面解决
产品价格--多货币的实现
多货币 它属于每个访客自定义的数据,所以它不能存储在Application中,应该存储在Cookie中,或者session中
Octopus使用是Cookie的方式实现的
不让Entity承担过多的业务逻辑
在写的过程中,为货币Cookie的问题困扰了好久,产品价格的计算需要,产品对象拿到货币对象之后才能进行
起初我是在Entity中读取Cookie值来获得货币对象,后来发现这样做不好
一是,每个产品对象的创建需要不能的读取cookie
二是,在ProductInfo 实体中承担了过多的业务处理逻辑
再者,好像在entity中不应该有访问Cookie之类的代码吧,
后来进行了改进,将这部分代码转移到业务层,在业务层中接收CurrencyInfo对象,对ProductInfo对象做属性的初始化,这样解决了这个问题
同时cookie的读取则转移到了表现层的Page_Load中,而且并不是直接访问cookie,而是在数据上下文容器中取得货币符号,进而得到货币对象来实现的
这个算是比较成功一次代码的升级
多语言的分页样式
分页样式也是一个比较重要的问题,Octopus是考虑多语言的,分页样式也是有一定多样性的
一般我们来实现就是编码生成 一段分页条的HTML代码片段,然后配合CSS样式实现分页,这个我参考了DTCMS中的代码,拿来主义
我感觉还是不错的,而且DTCMS上使用的是双top的分页算法,还是比较高效的
这是一种处理思路,Octopus就是这种方式实现的
第二种思路是,将分页条进行模板化,也有现成的代码,不过我没有采用这种方式,有点复杂,但是样式的可定义性,就非常的高
分页样式的处理和我后面介绍的关于无限级别分类的处理思路上是一样的。Octopus借助了NV模板引擎,所以在实现上要考虑NV引擎这一点
思路说完了,还是需要做一点改进的,前面第一种思路帮我实现了分页的算法问题,这个是解决掉了
那么多语言切换的时候,分页条该怎么变化呢?要和语言包定义的数据进行交互
比如:首页【中文】---First【英语】
我将生成分页条的OutPageList算法增加了一个params string[] langPage类型的参数,将里面固定的 字符使用传递进来的参数进行替换掉
牺牲掉了一部分的样式灵活性,在调用的时候,需要从NV引擎的数据上下文中读取定义的 首页 上一页 下一页 尾页 等数据 就可以了
备注:在页面周期的Page预加载事件中我们加载了语言包的数据【这个地方还需要做一定的优化,需要将数据进行一个缓存的处理】
这样分页条多语言的问题也解决掉了
无限分类的问题
无限分类的问题是最早开始解决的问题,也是花费时间比较长的问题,
大概有两个难点
一是:怎么设计无限分类的信息表,怎么存储无限分类的数据
二是:Octopus使用了NV引擎,产品分类的展示样式也是千变万化的,我在NV模板中该怎么写这样的代码呢?
先说第一个问题吧,表设计,其实大家都很清楚,有一个Parentid字段来标识当前分类的父分类ID,还会有一些附加的字段
ClassPath,记录分类的导航路径【一个分类ID以逗号分隔的一段字符】ClassLayer【节点的深度】,可以研究一下DTCMS中的设计
我基本就是参考它的。
还有一种设计方案叫做 左右值的无限分类 在网上有说明的,不过我没研究清楚,没法使用,基本就这两种吧,看大家怎么选择
下面一个比较关键的问题:如果所有分类读取出来放到NV引擎上展示出来?---后续会有
购物车的实现
提供几种思路实现
思路一:通过内置的OnPost自定义的Post机制实现
其内部的触发机制是:通过请求的参数个数来进行触发的
)
{
OnPost();
}
这种方式来处理页面的提交机制
然后通过两种方式区分页面发起的不同类型的请求
1.通过"成功控件实现"
2.通过"hd_action"隐藏域的类型来判断
不过这种方式 有个问题:用户在 右键单击 “重新加载”时 会提示重新 表单提交的问题
解决这个方式 也有两种方式:
1.使用${reload} js代码 响应到客户端,一旦用户触发页面的post事件时,就从服务端响应一段js脚本到客户端,在客户端在重新发起一次请求
这样就不会有 重复表单的提示。
2.后来发现可以不用这样做哦:使用Context.Response.Redirect(Request.RawUrl, true); 重新加载一次页面就可以了,一旦执行完毕post
的动作:更新,或删除,直接让客户端重新定向到新的URL发起一次请求,通过fiddler可以发现,每执行一个动作先是302的http代码,然后是200


两种方式都可以解决这个问题
使用js的方式 稍微慢了一点,因为post动作多执行了一次页面的周期Page_Load
优点:可以在任意的放加上任意多的form标记,这个和aspx只有一个form标记不同
既可以使用submit和image标签提交表单,也可以自定义函数调用表单的submit()函数从而完成表单的提交
还有就是不使用该死的脚本了,不用调试了 哈哈 只要有form就可以提交 简单死了
缺点:只要对象和服务端进行交互,就一定要有form标记,而且还有借助很多的隐藏标记
思路二:通过前台脚本的方式
前面说了上一种方式的实现 离不开form的标记,如果我们不用form标记,并且有时还要有get方式提交咋个办呢?
那就只能通过脚本Ajax的方式实现了
首先:如何存储自定义的数据,form中我们要存储自定义数据的话 使用的是hidden标记。使用思路二时: 使用data-*自定仪的属性
将一次请求所有用到的参数数据都存储在data-*里面,通过jq和js方式逐个获取,唉没有jq.serialize();的方法方便啊【后面自己写一个类似的方式实现data-*的批量获取】
function DomSerialize(dom)
{
if (dom)
{
var attr = dom.attributes;
var attrArr = [];
if (attr.length > 1)
{
//追加附加属性
for (var i = 0; i < attr.length; i++)
{
if (attr[i].name.indexOf("data-") != -1)
{
if (attr[i].name.indexOf("data-action") != -1)
{
attrArr.push(encodeURIComponent(attr[i].name.replace(/data-/, "my")) + "=" + encodeURIComponent(attr[i].value));
}
else
{
attrArr.push(encodeURIComponent(attr[i].name.replace(/data-/, "hd_")) + "=" + encodeURIComponent(attr[i].value));
}
}
}
//追加当前元素的属性
attrArr.push(encodeURIComponent(dom.name) + "=" + encodeURIComponent(dom.value));
}
return attrArr.join("&");
}
//attributes返回当前元素的所有属性数组 我们只选取包含data 开头的属性,并添加到当前数组中去,并将当前元素的name属性和value也添加进去
}
好了,准备工作完毕。接下来 发起请求就行了,通过ajax的请求配置包 common.js和Lee辅助脚本实现即可
对了,刷新说一下【如果请求成功将会执行】,使用js的方式进行刷新
思路三:使用ajax+模板的方式【名字还没想好先暂时到这儿】;
组件化的设想
已经实现了登录,购物车 ,注册等模块的组件化
会员中心的实现
实现思路有三种方式,第三种方式目前还不是很确定是否能实现
思路1:会员中心的实现都在一个ashx中实现,通过不同参数的传入,来实现不同的逻辑模块,实现不用模板的加载,同时将左侧的Left,作为一个Widget
思路2:反着来。实现一个母版页,通过if的判断语句,在右侧的加载各个组件
思路3:利用最原始的"子模板"的思路,这个还在思考中
Octopus系列之开发过程各个技术点的更多相关文章
- Intel系列CPU的流水线技术的发展
Intel系列CPU的流水线技术的发展 CPU(Central processing Unit),又称“微处理器(Microprocessor)”,是现代计算机的核心部件.对于PC而言,CPU的规格与 ...
- Octopus系列之如何让前台的js脚本变得灵活重用
Octopus系列如何让前台的js脚本变得灵活,重用 方式1:ajax方式 方式2:form表单方式 面向对象的脚本封装 jQuery的封装 做Web开发的少不了前台Ajax的使用, 返回true:f ...
- 单元测试系列之六:JUnit5 技术前瞻
更多原创测试技术文章同步更新到微信公众号 :三国测,敬请扫码关注个人的微信号,感谢! 原文链接:http://www.cnblogs.com/zishi/p/6868495.html JUnit ...
- 【ABAP系列】SAP DOI技术中I_OI_SPREADSHEET接口的使用
公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[ABAP系列]SAP DOI技术中I_OI_S ...
- 谈话节目APE系列:如何成为技术达人
作为一个程序猿,总有消退的前辈.或更年轻的同行.牛逼的人总是羡慕. 让我们搞自己痛苦的日子 BUG .头发很快结束了抓,人们扫两.修改一行代码.问题得以克服:例如,他们自己开发的十年,少付 10K , ...
- Java 数据持久化系列之池化技术
在上一篇文章<Java 数据持久化系列之JDBC>中,我们了解到使用 JDBC 创建 Connection 可以执行对应的SQL,但是创建 Connection 会消耗很多资源,所以 Ja ...
- Octopus系列之代码备份
代码 $.extend($.validator.messages, { required: "This field is required.", remote: "Ple ...
- Octopus系列之各个页面调用示例
调用首页产品 可选参数如下 New = 1, Hot = 2, Best = 3, Special = 4, Featured = 5, Other = 6 #foreach($item in $oc ...
- Octopus系列之模板快速开发手册
公共代码 html_header_1 <title>${sitename}-${seotitle}</title> <meta http-equiv="Cont ...
随机推荐
- 查看perl及其模块
Perl本身自带了很丰富的文档,如果把它们都打印出来,恐怕要耗费大量纸墨.我们试图清点过,但数到2000页左右的时候就数不清了(不用担心,我们用虚拟打印机计算页面数量,这样不会对树木造成威胁,挺环保的 ...
- jQuery的.click,.bind,.unbind,.on,.off,.delegate,.undelegate
.click与.bind .click和.bind都是给每个元素绑定事件,对于只绑定一个click事件,.bind事件的简写就是.click那种方式. 这两种方式都会出现两个问题: 第一个问题,如果要 ...
- 如何在eclipse jee中创建Maven project并且转换为Dynamic web project
如何在eclipse jee中创建Maven project并且转换为Dynamic web project 注意:该文档只针对以下eclipse版本,如图 为了方便,我将我本地的压缩包放在了微云网盘 ...
- opencv 61篇
(一)--安装配置.第一个程序 标签: imagebuildincludeinputpathcmd 2011-10-21 16:16 41132人阅读 评论(50) 收藏 举报 分类: OpenCV ...
- [转载] C++11中的右值引用
C++11中的右值引用 May 18, 2015 移动构造函数 C++98中的左值和右值 C++11右值引用和移动语义 强制移动语义std::move() 右值引用和右值的关系 完美转发 引用折叠推导 ...
- web设计经验<一> 提升移动设备响应式设计的8个建议
今天看到一些关于web设计的一些建议和设计经验,拿出来分享分享. 第一篇: 提升移动设备响应式设计的8个建议 一.直观性和易用性 在使用移动设备时,对于杂乱.复杂或者不直观的设计造成的混乱不佳的用户体 ...
- ecnu1624求交集多边形面积
链接 本来在刷hdu的一道题..一直没过,看到谈论区发现有凹的,我这种方法只能过凸多边形的相交面积.. 就找来这道题试下水. 两个凸多边形相交的部分要么没有 要么也是凸多边形,那就可以把这部分单独拿出 ...
- uva 10692 Huge Mods 超大数取模
vjudge上题目链接:Huge Mods 附上截图: 题意不难理解,因为指数的范围太大,所以我就想是不是需要用求幂大法: AB % C = AB % phi(C) + phi(C) % C ( B ...
- Linux配置全局环境变量的方法
总结3种方法: 1.修改/etc/profile 1.1 :首先在此文件中设置环境变量; 1.2:export 设置好的环境变量. #view /etc/profile export ...
- valueForKeyPath的妙用(转)
可能大家对 - (id)valueForKeyPath:(NSString *)keyPath 方法不是很了解. 其实这个方法非常的强大,举个例子: NSArray *array = @[@" ...