【问题标题】:Spring Webflow view iterationSpring Webflow 视图迭代
【发布时间】:2015-11-15 18:06:41
【问题描述】:

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

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

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

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

【问题讨论】:

    标签: jsp spring-mvc spring-webflow spring-webflow-2


    【解决方案1】:

    简要说明:

    我认为您通常误解了“视图状态”和 Spring webflow 的预期目的。

    Spring Webflow = 一个 xml 文件,描述了实现单一目标的状态的“顺序”逻辑流(例如,“预订机票”、“收集烹饪收据的信息”等。 ..)

    “顺序”在这里表示每个单独的状态(例如视图状态、操作状态、决策状态、结束状态)都是一个执行的单个单元在 Spring 网络流中。每个状态明确定义完成执行后“下一个”状态将是什么。例如,

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

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

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

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

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

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


    回答您的问题:

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

    下面定义的示例流程与 cmets(不是基于您的描述中的示例代码)。

        <!-- 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>
    

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

    你还问过:

    或者,有没有办法在 webflow.xml 中设置 可以在视图#1 jsp 表单中更新,然后在视图#2 中进行评估 不调用服务器函数?或者正在使用并输出一个 可能的解决方案?或者我可以使用请求参数吗?

    没有。将始终调用服务器。为什么不直接从存储在模型中的集合对象的大小推断出配方的数量?

    您可以enable SWF the handling of ajax requests 并将 requestParam 发送到未定义“to=”状态的转换。 (意味着它将保持当前视图状态)并在转换标签内执行您的自定义逻辑(请参阅:How to include a pop-up dialog box in subflow

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

    【讨论】:

    • 非常感谢您的详细回复。我昨天花了所有时间动态创建一个 href,其中包含 flowExecutionUrl、eventId 和所需的迭代次数作为 requestParam,直到我重新打开基本页面的验证并且很明显没有正确提交表单.最终,按照您的建议将@Transient 字段添加到模型中并在决策状态下使用它们是最有意义的。经验教训:不要用锯子敲钉子。再次感谢您的帮助。
    • 只是一个快速跟进,让您知道我能够根据您的建议让说明流程正常工作。由于该模型包含二维自动填充列表(部分标题的主列表和实际指令的子列表),因此需要大量的代码和索引。然而,当我完成这个工作时,我仍然不完全相信允许在 SWF 范式中重复单个页面必然是一件坏事。流程仍然是“连续的”,但给定的页面将简单地向用户呈现 x 次。
    • 空间不足,但要完成,无论是否考虑这个迭代建议,它都不太可能,因为似乎 Spring 对增强这个项目并不感兴趣。上一个主要版本 2.0 是在 2008 年 4 月。不过,使用它很有趣,我已经能够实现我想要的。再次感谢您的帮助。
    • @LWK69 很高兴听到它成功了。几个月前,他们刚刚发布了一个小版本。虽然 SWF 似乎没有得到积极的处理......在 jira 页面上提交增强请求我敢打赌你会在一两天内得到回复。
    • @LWK69 同样,如果您希望此功能是“可扩展的”,您可以将其放置在抽象父流中并利用流继承来利用它。这会有点复杂,但这是另一种解决方案。
    猜你喜欢
    • 1970-01-01
    • 2010-09-15
    • 2015-02-16
    • 2013-08-30
    • 1970-01-01
    • 1970-01-01
    • 2012-05-23
    • 2014-11-10
    • 2011-07-29
    相关资源
    最近更新 更多