【原创译文】创建你的第一个组件(3)

第三步

自定义新增服务

上面的例子里,createTutorial转换使用了隐式的自动实体服务create#Tutorial。我们来看下如何手动的定义和实现一个服务。

首先定义一个服务使用默认的自动实体增删改查(CrUD)实现。将服务定义XML文件放在下面的位置: runtime/component/tutorial/service/tutorial/TutorialServices.xml

内容如下:

标准的服务定义
1
2
3
4
5
6
7
8
9
10
<services>
  <service verb="create" noun="Tutorial" type="entity-auto">
      <in-parameters>
          <auto-parameters include="all"/>
      </in-parameters>
      <out-parameters>
          <auto-parameters include="pk" required="true"/>
        </out-parameters>
    </service>
</services>

这个服务将允许Tutorial实体的所有字段传入,并总是返回主键字段(tutorialId)。这个服务定义中我们使用了基于实体的auto-parameters元素,这样如果我们新增了实体字段的话,它们将自动会体现在这个服务处理中。 现在,我们修改下这个服务定义来添加一个内联的实现。注意下服务中的type属性已经发生了变化,并且新增了一个actions元素。

指定主键规则的服务定义
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<service verb="create" noun="Tutorial" type="inline">
  <in-parameters>
      <auto-parameters include="all"/>
  </in-parameters>
  <out-parameters>
      <auto-parameters include="pk" required="true"/>
    </out-parameters>
    <actions>
      <entity-make-value entity-name="Tutorial" value-field="tutorial"/>
      <entity-set value-field="tutorial" include="all"/>
      <if condition="!tutorial.tutorialId">
          <entity-sequenced-id-primary value-field="tutorial"/>
      </if>
      <entity-create value-field="tutorial"/>
  </actions>
</service>

现在只需改变transition指向这个服务既可以调用了:

切换自定义的服务
1
2
3
4
<transition name="createTutorial">
  <service-call name="tutorial.TutorialServices.create#Tutorial"/>
  <default-response url="."/>
</transition>

注意下这个服务名称定义很像一个标准的Java class的命名。它有一个“包名”,本例中是在component/service目录下的”tutorial”目录(也许是以点号分割的多重目录结构)的目录名。然后是一个点号以及类名的等价物,本例中“TutorialServices”就是服务的XML文件的名称,但是没有.xml后缀。这之后又是一个点号,然后是服务的动词和名词操作,以#符号分割。

Groovy服务

如果你想使用Groovy(或者框架支持的其他脚本语言)而不用内联的XML动作去实现服务,怎么做呢?这种情况服务定义像这样:

Groovy服务定义
1
2
3
4
5
6
7
8
9
<service verb="create" noun="Tutorial" type="script"
        location="component://tutorial/script/tutorial/createTutorial.groovy">
  <in-parameters>
      <auto-parameters include="all"/>
  </in-parameters>
    <out-parameters>
        <auto-parameters include="pk" required="true"/>
    </out-parameters>
</service>

注意这里服务的type属性已经变为”script”,并且现在有个location属性去指定脚本的位置。
下面是这个Groovy脚本的内容:

Groovy脚本
1
2
3
4
5
EntityValue tutorial = ec.entity.makeValue("Tutorial")
tutorial.setAll(context)
if (!tutorial.tutorialId)
  tutorial.setSequencedIdPrimary()
tutorial.create()

当你使用Groovy或者其他语言时,你将会用到基于可执行上下文(ExecutionContext class)这个类去调用Moqui的Java API,通常这个类在脚本里会用”ec“这个名称。更多的API详情请看Java API文档,并查询文档中ExecutionContext这个类,这个类关联了很多核心的API接口。




  • 作者: Eric Chang
  • 出处: http://gagaboy.github.io/
  • 本文基于 署名-非商业性使用-相同方式共享 3.0 中国大陆许可协议发布
  • 欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接以及作者(上方两项信息)否则:保留追究法律责任的权利。