Javashop模板制作手册V2

1、概述

  Javashop模板制作需要用到标签、api调用,在一些复杂的模板中还可能会用到url映射。

  我们以购物车页面为例介绍,购物车页面的样子可能如下所示:

  我们首先会用标签输出上述列表的数据,而对于删除和更改数量的功能性操作,我们通过异步调用核心的api来完成,我们使用删除购物车api操作为例,
如删除购物车一项的api地址为:/api/shop/cart!delete.do?cartid=1

调用上述地址会返回一个json串{“result”:1,”message”:”删除成功”}对于这些API详细请参见《Javashop API文档》

2、标签使用详解

  我们以输出上述购物车列表为例来调用标签输出数据:

  首先我们在当前模板文件夹中建立一个模板文件,如名为:"cart.html",然后在此页面中输入如下代码:

<#-- 创建购物车标签-->

<#assign  cartTag= newTag("cartTag")>

<#--通过购物车标签获取购物项列表 -->

<#assign  itemList = cartTag()>

<div class="cart-wrap">

  <#if (itemList?size>0)>

  <!--循环输出商品列表-->

    <li>

      <h6>${item.name}</h6>

      <h6>${item.num}</h6

      <h6><a href="javascript" itemid=" ${item.id}" class="del">删除</a></h6>

    </li>

  </#list>

  <#else>

    <h6>购物车没有商品!</h6>

  </#if>

</div>

  然后打开浏览器在地址栏中输入:/cart.html就可以看到效果了。(和v3.2不同的是去掉了uri的建立,不用再关心widget.xml,新建模板文件直接就访问就可以)

  我们来解释一下标签的使用,首先是标签的创建:

<#assign  cartTag= newTag("cartTag")>

assign这个关键字是Freemarker定义的,用来在模板中声明一个变量,

cartTag是声明的变量名,

newTag("cartTag")创建了一个购物车标签,并将引用赋值给了cartTag变量,

而下面这行代码是调用了刚刚创建的cartTag标签:

<#assign  itemList = cartTag()>

调用这个标标签会得到购物车的列表,上述代码把他赋值给itemList变量。这样我们就可以通过#list 指令来循环这个列表了。

Javashop标签的返回值请参见:《Javashop标签文档》

小提示

  在页面中可以直接获取在地址栏和form中传递的参数哦,如:/test.html?name=wf

  那么在页面中直接通过${name}就可以输出地址栏中定义的name参数。同样的地,form表单中的参数通过上述方法可以一直获取、输出。

3、API的调用

  我们还以上述购物车的删除操作为例,调用购物车删除api代码如下:

$(".cart-wrap  .del").click(function(){

  //得到cart id

  var  itemid = $(this).attr("itemid");

  $.ajax({

    url:"/api/shop/cart!delete.do",

    data:"cartid="+itemid,

    dataType:"json",

    success:function(result){

      if(result.result==1){

        alert("删除成功");

      }else{

        $.alert(result.message);

      }

      $.Loading.hide();

    },

    error:function(){

      $.alert("出错了:(");

    }

  });

});

  上述的api是通过访问一个url:/api/shop/cart!delete.do来调用的,调用结果是json格式,如:{“result”:1,”message”:”删除成功”}。对于这些API详细请参见《Javashop核心API详解》

4、模板制作高级篇

4-1、定义url-模板映射

  可能会有一些特殊的模板,如商品详细页,他的访问地址一般为:goods-1.html其中的1表示这个商品的标识id,通过这个id我们的商品详细标签才能由数据库中查询出此商品的数据,但我们有很多商品,不可能建立goods-1.html,goods-2.html...goods-1000.html,这么多模板,此时我们就要用到uri-模板映射,是通过正则表达式来完成的,如:我们建立如下的映射:

/goods-(\d+).html -> /goods.html那么访问所有的/goods-{数字}.html 这样的地址都会解析goods.html这个模板了。

5、标签开发指南篇

5-1、基本知识

  首先要继承于com.enation.framework.taglib.BaseFreeMarkerTag然后实现这个类的exec方法,如:

@Component

public  class  TestTag  extends  BaseFreeMarkerTag {

  @Override

  protected   Object   exec(Mapparams) throws  TemplateModelException{

    return"这是一个测试";

  }

}

  其中@Component是spring的注解,这样此类就会自动被spring扫描,并在spring容器中创建此类的实例,此实例的beanid为testTag,就是类名首字母小写。

  当然也可以通过如下方式指定beanid:

@Component("myTestTag")

  这个beanid就是标签的标识,也就是在模板页中如下红色的部分:

 <#assign  cartTag= newTag("cartTag")>

  标签的exec方法会在标签调用的时候被调用,也是就在模板中:

<#assign  itemList = cartTag() >

  这段代码会执行标签的exec方法。这个方法的返回值就是返回给页面的变量,如上述的itemList,可以反回任何值,字串、数字,List。。。都可以。

  在我们示例中返回了字串,现在可以在页面中输入如下代码:

<#assign  testTag= newTag("testTag")>

<#assign  myValue = testTag()>

返回值是:${myValue}

那么页面会输出exec方法返回的变量。

5-2、参数的传递

exec方法中的Map  params参数存储了由页面中传递过来的变量,如:

<#assign  testTag= newTag("testTag")>

<#assign  myValue = testTag ("{'catid':1}") >

像上面标红的示例一样,参数是通过json的格式传递的,那么在标签类中获取参数值如下:

protected  Object  exec(Mapparams) throws  TemplateModelException {

  Integer  catid = (Integer)params.get("catid");

  return"这是一个测试,catid是"+catid;

}

  参数的名字(catid),就是map参数的key,值得注意的是参数值的数据类型,上述例子的json串:{'catid':1},catid值就是Integer型,所以没有加引号,第二个例子就是String型:{'catid': '1'},所以要加引号。

小提示

1、javashop中的标签都已自动纳入spring的容器管理,所以在标签类中可以正常的注入使用spring的其它bean。

2、javashop为以下包名设置了spring的注解扫描:
  com.enation.app.base
  com.enation.app.shop
  com.enation.app.cms

3、如果在你的项目中需要扫描其它包名,请在spring配置文件中通过如下代码配置:

<!-- 定义此应用的组件扫描包 -->

<context:component-scanbase-package="com.enation.app.shop"/>

6、API开发指南

  首先值得说明的是,上述所说的API和正常的struts2 Action没有丝毫区别。只不过访问路径必须是在/api/下,这个目径下不会被模板机制拦截,可以正常的由struts2响应。

6-1、示例

  同样是要继承com.enation.framework.action.WWAction如:

@Component

@Scope("prototype")

@ParentPackage("eop_default")

@Namespace("/api/wine")

@Action("test")

public  class  TestApiAction  extends  WWAction {

public  String  delete(){

    this.showSuccessJson("成功啦");

    returnthis.JSON_MESSAGE;

  }

}

其中的注解:

@Component同样是让spring自动扫描为 spring  bean

@Scope("prototype")生命bean的生命周期为prototype,这是为了多线程时的数据安全。

@Namespace("/api/wine")是这个是根据你的项目需要定义的namespace,这个决定了你的api访问路径

@Action("test")定义这个action的访问路径。

像上述示例的api,需要通过如下地址访问:/api/wine/test!delete.do这样就会调用delete方法,这个api的返回结果会是:

{"result":1,"message":"成功啦"}

返回的json串的规范对于我们意义重大,我们规定:

 1、json串中必须含有结果值,我们规定用result来表示,1表示成功,0表示失败

 2、json串的名称部分必须用双引号,字串值也必须用双引号(否则jquery1.4以后的版本不支持)

javashop提供了常用方法帮助大家生成json串,这些方法有:

基类WWAction中的方法:

1、showSuccessJson返回成功结果的字串,如:

  this.showSuccessJson("成功啦");

  返回:

  {"result":1,"message":"成功啦"}

2、showErrorJson返回失败的字串,如:

  this.showErrorJson("出错啦");

  返回:

  {"result":0,"message":"出错啦"}

  如果我们需要返回更复杂的json串时该怎么办呢?

  实际上我们是通过为WWAction基类的json属性赋值来实现向客户端返回字串的,比如调用this.showSuccessJson("成功啦");
实际是做了如下操作this.json=”{\"result\":1,\"message\":\"成功啦\"}”

  如果需要返回更复杂的json串,那么构造好字串并赋值给json属性就可以了。

  Javashop提供了com.enation.framework.util.JsonMessageUtil工具类来帮助生成json串,具体请参考此类。

小提示

1. javashop为以下包名设置了struts的注解扫描:
  com.enation.app.base.core.action
  com.enation.app.shop.core.action
  com.enation.app.cms.core.action
  如果在你的项目中需要扫描其它包名,请在struts配置文件中通过如下代码配置:

  <constantname="struts.convention.action.packages"value="com.enation.app.shop.core.action"/>