Spring Webflow 视图迭代

Spring Webflow view iteration

我已经使用 SWF 工作了大约 3 周,我成功地将 Spring MVC/JSP 食谱输入表单移植到 4 个单独的视图中,包括 1) 基本信息,2) 成分, 3) 说明和 4) 可选信息。我想增强流程,以便 #2 and/or #3 可以根据 #1 上的用户条目执行 1 到 x 次。一个示例是包含一组蛋糕配料和一组单独的糖衣配料的食谱 - 用户将在视图 #1 上指示有 2 组配料,而视图 #2 将显示两次。

我已经通读了文档和大量帖子,但对于解决此问题的最佳方法,我仍然感到很困惑。本质上,我需要在视图 #1 中设置一个变量,webflow 将评估该变量并在视图 #2 上执行一种 for 循环。

目前,迭代次数不是视图使用的模型的一部分,但似乎我看过的大多数示例和帖子都指出需要将其添加到模型然后执行 <evaluate> 在流程中确定迭代视图 #2 的次数。或者,有没有办法在 webflow.xml 中设置 <var> 可以在视图 #1 jsp 表单中更新,然后在视图 #2 中评估而不调用服务器函数?或者使用 <input>output 是一种可能的解决方案吗?或者我可以使用请求参数吗?

我不得不承认对此有点困惑。任何帮助我指出示例、文档和其他我以某种方式错过的帖子的帮助都将不胜感激。

简要说明:

我认为您误解了 'view-state' 和 Spring 网络流程的一般用途。

Spring Webflow = 一个 xml 文件,描述了 "Sequential" 实现单一目标的逻辑状态流(例如 'Book an airline ticket', 'Gather information for cooking receipes', 等等...)

"Sequential" 这里的意思是每一个状态(例如视图状态、动作状态、决策状态、结束状态)都是一个 Spring webflow 中的单个执行单元。每个状态 EXPLICITLY 定义 'next' 状态在完成执行后的状态。例如,

(view-state A) -> (action-state B) -> (decision-state C) -> (end-state D)

在每个状态中没有定义迭代的概念,因为它们是单个执行单元。一旦一个状态完成执行,它必须进入 'transition' 标签定义的下一个状态。

<view-state id="stateA">
     <transition to="stateB"/>
</view-state>

另请注意,我在引号中写了 "Sequential",因为尽管流程是顺序的(从状态 -> 状态)...我们仍然可以跳回我们希望的任何状态。

(view-state A) -> (action-state B) -> (decision-state C) -> (view-state A)

所以...您对内部视图状态迭代的解释不存在。


您问题的答案:

有几种方法可以实现您想要的 'state' 迭代,但听起来您需要一个决策状态来根据某些 flowScope 变量委托流程。基本上,您想跟踪要执行特定状态的次数,然后每次执行该状态时,您都会将变量递减 ( 1 ) 并重新评估它,直到执行次数 == 0。

下面定义的示例流程 带有注释(并非仅基于您描述的示例代码)。

    <!-- define the 'global' flowScope variable that will track the num of times you want to execute the ingredients state --> 
    <set name="flowScope.numOfTimesToExecuteIngredientsState" value="0" type="java.lang.Integer"/>


        <view-state id="basicInfoState" model="basicInfoModel">

        <!-- initially goto the decision state and make sure to set the num of execution inside the transition to the 'global' flowScope tracking variable -->
        <transition on="save" to="ingredientsIteratorDecisionState">
 <!-- assuming ingredients is an initialized Set<Ingredients>... get the size and put inside a flowScope var -->
             <set name="flowScope.numOfTimesToExecuteIngredientsState" value="basicInfoModel.getIngredients().size()"/> 
        </transition>

        </view-state>

        <decision-state id="ingredientsIteratorDecisionState">
            <!-- if # of executions is more than 0 go back to ingredientState otherwise move on to instructionsState -->  
            <if test="flowScope.numOfTimesToExecuteIngredientsState > 0" then="ingredientsState" else="instructionsState"/>
        </decision-state>

        <view-state id="ingredientsState">

            <transition on="save" to="ingredientsIteratorDecisionState">
              <! -- upon a successful save... decrement numOfIngredientsSelected by ( 1 ) -->
              <set name="flowScope.numOfTimesToExecuteIngredientsState" value="flowScope.numOfTimesToExecuteIngredientsState - 1"/>
            </transition>
        </view-state>

免责声明: 上面的流定义没有经过测试。我只是凭记忆写的。可能存在语法错误。

您还问了:

Alternatively, is there a way to set a in the webflow.xml that can be updated in the view #1 jsp form and then evaluated in view #2 without calling a server function? Or is using and output a possible solution? Or could I use a requestparam?

没有。总会有对服务器的调用。为什么不从模型中存储的集合对象的大小中推断出食谱的数量?

你可以enable SWF the handling of ajax requests and send a requestParam to a transition with no defined 'to=' state. (meaning it will stay in the current view-state) and inside the transition tag do your custom logic (see: )

但我认为这是一个设计问题。您传递的所有值都应该在单个 http 请求中(因此是模型的一部分)。