PeopleSoft PeopleTools移动应用开发
上QQ阅读APP看书,第一时间看更新

2.3 流动设计模式

除了流动页面与经典页面之间显而易见的差异之外,Fluid对事务进行了重新设计。Fluid强调的是移动优先。我们都知道传统的数据输入方式在面向触摸的移动设备上是很难使用的。在移动设备上,屏幕分辨率、输入方式以及网络带宽都是受到约束的。

Fluid迫使我们以不同的方式思考如何输入和处理数据,迫使我们解决以下问题:

•如何减少用户交互(通过触摸、输入等方式)的次数?

•哪些数据是处理特定事务时必须可见的?

•为了完成特定事务,用户需要访问多少页面?

传统的PeopleSoft设计模式从一个主页面开始。接下来让我们计算一下完成一次典型的业务流程所需要的交互次数。首先,用户通过主页面(1次)与一个菜单进行交互(2次),从而导航到一个事务搜索页面。在搜索页面上(3次),用户输入搜索标准(4次),并搜索特定的事务(5次)。然后用户选择一个事务(6次),并开始处理相关信息。由此可见,到达事务处理页面共需要6次交互。许多人都满足于使用这种传统模式,甚至不考虑到达事务页面所需要的过程。多年来,PeopleSoft也提供了许多强化功能来简化事务访问,比如Pagelets和WorkCenters。但Fluid打破了标准的开发模式,迫使我们改变以前所用的开发模式。前面已经看到,流动导航是不同的。它主要是通过主页面、收藏夹以及最近的位置来进行导航。同样,事务搜索也不再是自由的(这一点非常好,因为每种事务都是不同的)。

新模式

让我们重新思考一下事务访问策略(导航和搜索)。如果搜索结果始终存在,就像是事务的一部分,那么事务访问策略应该是什么样的呢?在前面的示例中,搜索结果是一个字段列表。接下来让我们将该列表放置到左边的侧边栏中。

1.搜索记录

组件左边的列表是搜索页面。在本例中该列表是一个字段的摘要列表。首先创建带有两个字段的新记录定义:FIELDNAME和COUNT1。然后将记录类型更改为SQL View,并将其保存为BMA_XLAT_FLD_VW。此时,我们将进行一些修改,让0级记录表示一个带有真实数据的PeopleTools表。因为0级记录是只读的,所以该修改没有问题。但1级记录是可读写的,因此将该记录与一条模拟记录相关联,以防止意外地损坏元数据。下面所示的SQL从模拟的1级记录中进行选择,而不是从PeopleTools表中。请将下面的SQL输入到视图的SQL编辑器中,然后生成视图。

    SELECT FIELDNAME
        , COUNT(*)
     FROM PS_BMA_XLATITEM
    GROUP BY FIELDNAME

在继续后续操作之前,请确保构建了记录定义,并选择了Create Views选项。

2.双面板(two-panel)布局

创建一个使用了PSL_TWOPANEL布局的新流动页面,并命名为BMA_XLAT_2PNL_FL。此时,Application Designer应该显示一个包含了一系列嵌套分组框的流动页面。而最里面的集合应该包含两个分组框,左边一个稍窄,右边一个稍宽。后面将主要使用分组框panel action-interior和apps content。所以请删除apps content分组框中的空白分组框,而较小的内部分组框则不会使用。图2-18显示了Application Designer的双面板布局的屏幕截图。

图2-18 PSL_TWOPANEL布局

apps content分组框应该包含与BMA_XLAT_FL页面相同的网格。重新创建该网格的最简单方法是从BMA_XLAT_FL页面定义中复制网格,并将其粘贴到apps content分组框。粘贴(或者重新创建)网格后,打开网格属性对话框并切换到Use选项卡。选中No Auto Select选项。与BMA_XLAT_FL页面不同,该事务页面并没有使用0级来告诉组件处理器选择哪些行。相反,使用了PeopleCode来填充Translate Values网格。

注意:

如果查看一下PeopleSoft所提供的流动内容,会发现许多的流动页面都包含了子页面,而不是标准的页面内容。一些开发人员往往习惯创建带有内容的子页面,并将这些子页面添加到布局,而不是直接将内容添加到布局中。这纯粹是出于个人偏爱和便利。使用子页面所带来的一个优点是可以在经典和流动页面中嵌套相同的子页面。

布局的左侧还包含了一个网格,但并不希望它看起来像一个网格,而是希望屏幕的左侧看起来像一个iPhone或者Android列表视图。我们将使用PeopleSoft预定义的CSS3类来获取所需的外观。请将一个新的网格拖放到panel action-interior分组框。打开网格属性对话框,并在General选项卡中完成下面的更改:

•将主记录和页面字段名设置为BMA_XLAT_FLD_VW。

•选择Unlimited Occurs Count。

接下来需要禁用许多标签选项。所以请切换到Label选项卡。例如,为了关闭行计数器,请单击导航栏的Properties按钮,然后切换到Row Cntr选项卡。最后选择Invisible复选框,关闭行计数器。如果想要禁用导航栏,可以取消选择Display Navigation Bar复选框。在网格属性对话框中滚动到Body区域,并取消选择Show Row Headings。同样,取消选择Show Column Headings。

在Use选项卡中,选择以下项目:

•No Row Insert

•No Row Delete

•Display Only

在Use选项卡的底部,将网格布局更改为List Grid Layout。切换到Fluid选项卡,将Default Style Name设置为psc_list-linkmenu。

向左边的网格添加一个按钮/超链接字段。打开按钮的属性,并将其标记为一个超链接,然后将Field Name属性设置为FIELDNAME。切换到Label字段,将Label Type更改为Text。当用户单击此超链接时,PeopleCode将对右边的网格进行过滤,从而只显示所选字段的转换值。因为想要在用户单击(或者触摸)某一行时执行PeopleCode,所以切换到Use选项卡,并选择Execute PC on Row/Group Click选项。同时选择Enable When Page is Display Only选项。

向网格添加BMA_XLAT_FLD_VW.COUNT1字段。接下来,我们希望将转换值计数显示在列表右侧的一个小圆圈中,类似于员工自助流动页面中批准和反对的显示方式。打开该字段的属性,切换到Fluid选项卡,向Default Style Name属性添加psc_list_count样式类。

3.智能组件

与第一个示例(第一个示例中所创建的页面包含了所有必需的数据绑定元数据)不同的是,该页面包含了许多结构和引用。例如,在没有PeopleCode干预的情况下,页面左侧的超链接将不会显示字段名称。同样,如果没有用一些PeopleCode来选择正确的值,右边的网格也不会显示任何数据。接下来,让我们创建一个组件,并编写一些PeopleCode。

创建一个名为BMA_XLAT_2PNL_FL的新组件。打开组件的属性,并完成下面的更改:

•将搜索记录设置为INSTALLATION。

•禁用Add操作(位于搜索记录右侧的Use选项卡)。

•在Internet选项卡中,取消选择Display Folder Tabs。

•切换到Fluid选项卡,并选择Fluid Mode复选框。

添加BMA_XLAT_2PNL_FL页面,并将其Item Label设置为Maintain Translate Values。从Application Designer菜单栏中选择View|View PeopleCode,打开组件的PeopleCode编辑器。滚动左上角的对象列表,找到BMA_XLAT_FLD_VW记录,然后在右边找到RowInit事件。向PeopleCode编辑器添加下面的代码。图2-19显示了组件的PeopleCode编辑器的屏幕截图。

图2-19 PeopleCode编辑器

    BMA_XLAT_FLD_VW.FIELDNAME.Label = BMA_XLAT_FLD_VW.FIELDNAME

使用类似于前面的组件所使用的值注册该组件。将其添加到一个菜单、门户注册以及权限列表中。然后选择BMA_FLUID菜单,并将内容引用标签和描述设置为BMA Maintain Translate Values。最后使用PTPT1200权限列表,结束向导。

注册完之后,如果想要测试该组件,可以访问Protal Registry中的Content Reference,然后单击Test Content Reference。通过使用导航PeopleTools|Portal|Structure and Content,可以在网上找到Portal Registry。新组件在Fluid Structure and Content|Fluid Pages|BMA PeopleTools中注册。图2-20显示了带有侧边栏的新组件的屏幕截图。

图2-20 带有侧边栏的响应式Translate Values页面

注意:

如果组件看起来更像一个经典组件而不像流动组件,那么请检查是否在组件属性的Fluid选项卡中选择了Fluid Mode。

返回到Application Designer,并在BMA_XLAT_FLD_VW.FIELDNAME FieldChange事件中输入下面的PeopleCode。当用户在左边面板中选择了一行时,组件处理器将调用该PeopleCode。

    REM ** Row selection container;
    Component Row &selectedRow;

    Local Row &r0 = GetLevel0().GetRow(1);
    Local Rowset &xlatRs = &r0.GetRowset(Scroll.BMA_XITMMNT_VW);
    Local string &fieldName = GetField().Value;

    &xlatRs.Flush();
    &xlatRs.Select(Record.BMA_XITMMNT_VW, "WHERE FIELDNAME = :1",
          &fieldName);

    If (All(&selectedRow)) Then
      &selectedRow.Style = "";
    End-If;

    REM ** Update the selected row style class;
    &selectedRow = GetRow();
    &selectedRow.Style = "psc_selected";

保存并在Web浏览器中重新加载页面。从左边的列表中选择一项,会看到网格包含了相关的数据。

目前,该页面还存在一个小问题。当页面首次显示时没有选择任何行。接下来,使用一些组件PostBuild PeopleCode来解决该问题。请向组件的PostBuild事件中添加下面的代码:

    REM ** Row selection container;
    Component Row &selectedRow;

    Local Row &r0 = GetLevel0().GetRow(1);
    Local Rowset &xlatRs = &r0.GetRowset(Scroll.BMA_XITMMNT_VW);
    Local string &fieldName;

    &selectedRow = &r0.GetRowset(Scroll.BMA_XLAT_FLD_VW).GetRow(1);
    &fieldName = &selectedRow.GetRecord(Record.BMA_XLAT_FLD_VW).GetField(
          Field.FIELDNAME).Value;

    &xlatRs.Select(Record.BMA_XITMMNT_VW, "WHERE FIELDNAME = :1",
          &fieldName);

    REM ** Update the selected row style class;
    &selectedRow.Style = "psc_selected";

注意:

你是否已经厌倦了在浏览器的选项卡或者页面标题中看到诸如BMA_XLAT_2PNL_FL之类的含义模糊的文本?至少我是厌倦了。为此,可以在菜单定义中更改该项目的标签。

如果设备屏幕足够宽,那么你可能更愿意看到左边的侧边栏默认情况下处于展开状态,而不是折叠状态。请向Page Activate事件添加下面的PeopleCode,从而迫使侧边栏默认情况下处于展开状态:

    Declare Function initializeTwoPanel PeopleCode
    PT_TWOPNL_WORK.BUTTON FieldFormula;

    initializeTwoPanel(1, False, Null, 0);

图2-21显示了最终的双面板Maintain Translate Values组件。

图2-21 双面板Maintain Translate Values组件

Application Class控制器

在上面的代码中,你是否看到了FieldChange和PostBuild事件共享的重复代码?这两个事件都更新了选择行,并填充了Translate Values网格。针对DRY(Don't Repeat Yourself)代码,PeopleCode开发人员所采用的一种策略是在Application Classes中编写业务逻辑。甚至有些开发人员将所有的业务逻辑都写在Application Class中,并将这些类作为组件控制器来使用。由于PeopleTools平台已经拥有了组件控制器,因此个人不太喜欢使用Application Class控制器模式。然而,Application Classes也是非常有用的。例如,Application Designer不允许开发人员保存包含了未声明变量的Application Class。我就曾经花费了大量的时间来尝试解决由于拼写错误的变量所引起的问题。使用Application Classes的另一个主要原因是便于进行测试驱动开发。虽然不能针对基于组件事件的PeopleCode编写测试代码,但可以使用PSUnit来测试Application Classes。尽管目前的趋势是更多的业务逻辑从基于事件的PeopleCode转移到Application Classes,但我的做法是仍然坚持使用基于事件的PeopleCode,只有当有意义时才会创建Application Classes。在前面的示例中,将通用代码封装到一个Application Class中是很有意义的。相反,其中一个PeopleCode事件只需要一行PeopleCode。此时如果将那一行代码转移到Application Class中,将会导致代码行数成倍增加。

注意:

在本章,我们使用了多个已发布的CSS类。在构建流动组件时,可能还需要创建自己的CSS定义。通过使用新的AddStylesheet PeopleCode功能,可以将自定义的CSS样式表包含到流动组件中。