自定义了页面周期

使用唯一的一个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:利用最原始的"子模板"的思路,这个还在思考中

最新文章

  1. Object转数组
  2. 调用JavaScript
  3. Shell编程中括号判断中赋值语句和判断语句
  4. 小甲鱼python视频弟十二讲(关于字符串的方法及注释下)
  5. iOS端给unity发送消息,实现两者交互。
  6. HTML5小游戏【是男人就下一百层】UI美化版
  7. SpringMVC 注解事务
  8. 解决Unable to load R3 module ...VBoxDD.dll (VBoxDD):GetLastError=1790
  9. UVa 1252 (状压DP + 记忆化搜索) Twenty Questions
  10. ASP.NET常用技巧方法代码断
  11. CentOS 开启GD库
  12. TestNG目录
  13. java浮点数剖析
  14. 在IT公司,project manager 基本上和秘书,助理什么的差不多
  15. 《OdooERP应用与开发基础》试读:第一章-Odoo概述
  16. [原]Jenkins(十六) jenkins再出发之jenkins+robot+blue ocean+svn
  17. 微信小程序textarea组件在fixed定位中随页面滚动
  18. debug protractor
  19. jvm虚拟机--垃圾回收子系统
  20. [Object Tracking] MeanShift

热门文章

  1. 《Linux内核设计的艺术》学习笔记(二)INT 0x13中断
  2. 百度翻译word-wrap,页面错乱原因查找过程(已修复)
  3. jquery 跳转到当前页面指定位置
  4. [转载] zookeeper faq
  5. (一)SecureCRT连接虚拟机linux
  6. jQuery动态加载css文件实现方法
  7. 阿里云+wordpress搭建个人博客网站
  8. listview某一项不可点击
  9. redis+tomcat+nginx session共享
  10. on delete cascade 和on update cascade