gpt4 book ai didi

grails - Grails:命令对象, View 模式和条件表单字段?

转载 作者:行者123 更新时间:2023-12-02 15:23:22 25 4
gpt4 key购买 nike

我正在尝试正确使用Command Objects。我有一些问题。

给定一个通用域,例如:

package com.foo

class Ticket {

Customer customer
Product product
Defect defect
Solution solution
String comment

static constraints = {
customer nullable:false
product nullable:false
defect nullable:true
solution nullable:true
comment nullable:true
}
}

然后,考虑 票证形式的以下 规则:
  • 客户只能在创建时选择。编辑时,选择不得
    被显示,改为显示标签;
  • 产品只能在创建时选择。但是,在编辑时,必须将select 显示为disable
  • 可以在创建或编辑时选择缺陷。
  • 解决方案不能以这种形式设置
  • 注释只能由具有特定角色的用户通知(例如,使用SpringSecurity)。如果用户没有这样的角色,则必须将文本区域显示为禁用。

  • 现在,我想知道的是:
  • 使用CommandObject处理的最佳方法是什么
    这种情况?
  • 两个 Action 都有1个CommandObject?
  • 1每个操作都特定的CommandObject?
  • 在单个CommandObject的情况下,例如,如何防止用户通过禁止参数来入侵程序?
  • 什么是实施表单规则的最佳方法?即,在每种情况下显示/启用/禁用哪个字段。
  • 在这种情况下是否有任何模式或建议?
  • 是否应以实际形式编写此类规则?
  • 还是应该“询问”某人? CommandObject也许是?还是域实例本身?

  • 例如,考虑以下形式的要点:
    <div class="fieldcontain ${hasErrors(bean:ticketInstance, field:'customer', 'error')} required">
    <label for="customer">
    <g:message code="ticket.customer.label" default="Customer" />
    <span class="required-indicator">*</span>
    </label>
    <g:if test="${ticketInstance.id}">
    <span class="label read-only">${ticketInstance.customer.name}</span>
    </g:if>
    <g:else>
    <g:select id="customer" name="customer.id" from="${Customer.list()}" optionKey="id"
    required="" disabled="" value="${ticketInstance?.customer?.id}" class="many-to-one"/>
    </g:else>
    </div>

    在这种情况下,没有什么问题,因为检查非常简单。那是:
    <g:if test="${ticketInstance.id}">
    ...

    但是,请考虑更复杂的规则。就像是:
    <g:if test="${ticketInstance.id && currentUser.granted('SOME_RULE') && ticketInstance.someField != null}">
    ...

    等等。

    现在,这种方法存在一些问题:
  • 相当冗长,因此容易出错。
  • 假设在其他字段中共享了这样的规则。在这种情况下,我将不得不以某种方式进行管理(局部变量,重复代码等)。
  • 而且,为此,我在TicketCommand中需要一个属性“Id”,但我不知道这是否是一个好主意。

  • 因此,我想知道是否有任何模式或建议可以用来改善这些情况。也就是说,某些东西将封装这种复杂性。例如:
    <g:if test="${cmd.customerAllowed}">
    ...

    CommandObject可能是一些东西:
    @Validateable
    class TicketCreateCommand {

    def currentUser //injected somehow..

    Customer customer
    Product product
    Defect defect
    String comment

    static constraints = {
    importFrom Ticket
    }

    boolean isNew() {
    true
    }

    boolean isCustomerAllowed() {
    this.new && currentUser.granted('SOME_RULE') && this.someField != null
    //some more rules if necessary..
    }

    boolean isSomeFieldAllowed() {
    //rules for creating
    }
    }

    和一个CommandObject用于编辑:
    @Validateable
    class TicketEditCommand {

    def currentUser //injected somehow..

    Customer customer
    Product product
    Defect defect
    String comment

    static constraints = {
    importFrom Ticket
    }

    boolean isNew() {
    false
    }

    boolean isCustomerAllowed() {
    this.new && currentUser.granted('SOME_RULE') && this.someField != null
    //some more rules if necessary..
    }

    boolean isSomeFieldAllowed() {
    //rules for editing
    }
    }

    CommndObject可以承担此类责任吗?如果没有,还有其他更好的方法来集中这些复杂性吗?另外,正如我之前说过的,不能在更新时设置属性(property)客户。怎么处理呢?

    好吧,我认为这差不多了。

    我将不胜感激任何意见和建议。任何教程的任何链接都将是出色的。

    PS:对于那些想看看的人,完整项目可以在 github上找到。

    最佳答案

    使用命令对象处理这种情况的最佳方法是什么?

    对于“查看”,“编辑”和“删除”操作,将需要票证的简单ID。我觉得那个阶段的命令对象是过大的。

    由于在更新(编辑提交操作)和保存(创建提交操作)中使用的表单背后有逻辑,因此您应该尝试为每个表单创建一个命令对象。

    我个人对命令对象的结构的偏爱是使其反射(reflect)表单提供的数据。然后,您可以在命令对象/ Controller 中使用实用程序方法,以从提供的数据中构造/获取Ticket

    什么是实施表单规则的最佳方法?

    表单的规则可以作为一系列条件语句写在gsp中。如果有较大的条件语句,或者在整个应用程序中经常重复使用的条件语句,则可以将方法添加到命令对象中,以使此语句集中化。

    由于命令对象位于 View 和 Controller 之间,因此我看不到为什么无法在此处存储表单逻辑。

    如果应禁用字段,则可以将disabled="disabled"属性简单地添加到表单字段。或使用命令对象方法:

    disabled="${cmd.isFooFieldDisabled() ? 'disabled' : ''}"

    如果该字段应该被隐藏,那么您可以像这样使用隐藏的输入,该值对用户将不可见,但将在表单提交时传递到命令对象中。
    <input type="hidden" name="foo" value="${ticket.foo}"/>

    我相信spring安全插件提供了 are tags provided来显示/隐藏gsp元素,具体取决于用户的角色。

    为了防止用户传递无效数据,您可以使用以下代码在 Controller 中对此进行验证。
    def foo(FooCommand cmd)
    {
    if(cmd.hasErrors())
    {
    // Handle validation errors
    }
    }

    方法 hasErrors使用您定义的约束来验证命令对象。此时,您可以返回错误或从验证错误中恢复并继续操作流程。

    如果用户更改了隐藏的表单输入(例如,对象的ID),则 Controller 代码应检查用户是否有权编辑具有给定ID的对象。如果他们这样做,那么安全策略就不会被破坏。如果不是,则可以返回您选择的错误。有关保护隐藏字段的信息,请参见 this post

    关于grails - Grails:命令对象, View 模式和条件表单字段?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32043760/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com