【问题标题】:When to use parameterized method invocations introduced with EL 2.2 (especially in JSF 2.x )?何时使用 EL 2.2 引入的参数化方法调用(尤其是在 JSF 2.x 中)?
【发布时间】:2013-12-29 02:24:20
【问题描述】:

过去,我使用了很多 getter 和 setter 方法来将尽可能多的布尔逻辑从 facelet 文件移动到 JSF 支持 bean。 这样,视图的接口由其支持 bean 的 getter 和 setter 方法以及支持 bean 的操作方法提供。 这种方法的一个优点是 facelet 文件是相当无逻辑的,因此,所有逻辑都在支持 bean 中并且可以进行单元测试。

但是在 EL 2.2 中,另一种编程风格成为可能。在 EL 2.2 中,您可以使用如下表达式调用方法

#{bean.collection.size()},
#{bean.collection.add(elem)},
#{bean.property.substring(0, bean.property.indexOf(something))}.

现在使用参数化方法调用等相当复杂的表达式是一种好的风格,还是建议不要使用这样的表达式? 是否有经验法则何时使用新方法调用表达式,何时不使用?

【问题讨论】:

    标签: jsf jsf-2 el


    【解决方案1】:

    主要准则如下:从视图中减少尽可能多的“模型”逻辑,只保留“视图”逻辑。 EL 2.2 使某些模型简化成为可能,并减少了创建 JSF bean 的人工属性的需要。使用参数调用方法还可以将必要的信息从视图传递到控制器,如果没有这个机会,这将是乏味的。

    您可以调用任意方法从视图部分所依赖的视图中访问模型,但切勿从视图中调用修改模型的方法

    让我详细说明一下。

    一些法律示例:

    1. 在构建视图时评估非访问器方法:
      • 根据rendered="#{request.isUserInRole('administrator')}"等条件渲染UI组件;
      • 在必要时进行集合修改,例如<ui:repeat value="#{bean.set.toArray()}" ... >
      • 有条件地评估 UI 组件/HTML 元素属性,例如 class="#{bean.name.contains('special') ? 'special' : ''}";
      • 输出非访问器数据,如there are #{bean.list.size()} 元素。
    2. 在动作方法或侦听器中将信息传递给控制器​​:
      • 使用当前迭代的变量执行操作方法,例如 var="data"action="#{bean.action(data)}"public String action(Data data)
      • varStatus="status"actionListener="#{bean.action(status.index)}"public String action(int index) 等侦听器中传递其他数据,例如当前迭代索引。

    一些要避免的例子:

    1. 尽可能使用 EL 运算符:
      • 使用#{not empty bean.list} 而不是#{bean.list.size() gt 0}
    2. 使用带参数的方法调用而不是扩展模型:
      • 使用#{bean.name.contains('special')} 而不是#{bean.special}public boolean isSpecial() {return name.contains("special");}
    3. 更喜欢将视图逻辑保留在视图中,以便简单地呈现正确的事物,并创建模型逻辑以防它纯粹应用于模型:
      • 如果您需要执行一些计算来更改对象的外观,请直接在视图中执行此操作而不更改模型,如果某些属性是模型本身固有的,请直接在模型中引入并引用它从视图。

    一些不合法的例子:

    1. 从视图中修改模型:
      • 不要使用 EL 2.2 调用带参数的方法来打破 MVC 范式的可能性,即不要从视图端调用 #{bean.list.add(element)}

    当然,上述所有内容都适用于您的目标不包含针对没有 EL 2.2 支持的旧服务器的情况。

    作为一个更大的图景,我建议也看看 BalusC 对what MVC architecture represents within the context of JSF 的解释。

    【讨论】:

    • 关心扩展“非法”位?由于在 JSF you don't implement a controller 中,视图 可以修改模型。
    • @mabi:控制器是什么,取决于观点:stackoverflow.com/questions/5104094/…
    • @mabi 在 JSF 中,前端控制器与托管 bean “共享”一些责任,即操作方法和操作/ajax 侦听器。您可以看到它们是从前端控制器调用的,这是通过托管 bean 方法完成的工作的一部分。托管 bean 的另一部分是通常作为组合完成的模型,即作为 bean 属性。
    • @BalusC 是的,但由于 MVC 一词有不同的观点,我不认为它是我不应该这样做的唯一原因。如果是业务流程,您仍然需要支持 bean/服务来执行多步算法。
    • 哦,#{bean.string.replace('old', 'new')} 是一个不好的例子,因为它不会修改模型。 @mabi:视图应该只访问模型,而不是修改它。控制器(托管 bean 实例)是唯一负责的。否则模型将紧密耦合到视图中,您无法添加例如记录器/拦截器/预后处理等。
    【解决方案2】:

    就个人而言,我更喜欢在真正需要时使用“复杂”的 EL 表达式,并对相应的托管 bean 采取任何位逻辑/特征。
    例如:你放的第一个例子是我有时可以直接使用的唯一一个,但是另外两个应该是我根据需要放入带有void/String返回类型的操作方法。

    【讨论】:

      【解决方案3】:

      使用 El 2.2 来减少我们的 JSF 代码,例如setPropertyActionListener 变得多余,请参阅 JSF Core Tag :setPropertyActionListener vs attribute vs param

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-04-11
        • 2012-01-09
        • 2012-04-29
        • 1970-01-01
        • 2013-12-16
        • 2023-04-10
        • 1970-01-01
        相关资源
        最近更新 更多