Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/jsf/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
JSF如何临时禁用验证器以保存草稿_Jsf_Validation - Fatal编程技术网

JSF如何临时禁用验证器以保存草稿

JSF如何临时禁用验证器以保存草稿,jsf,validation,Jsf,Validation,我有一个非常复杂的表单,有很多输入和验证器。对于用户来说,这需要相当长的时间(甚至超过一个小时)才能完成,因此他们希望能够保存草稿数据,即使它违反了规则,如未键入必填字段 我相信这个问题在许多web应用程序中都很常见,但找不到任何公认的模式来实现它。你能告诉我如何做到这一点吗 目前,我可以看到以下选项: 在“保存草稿”按钮上使用immediate=true不起作用,因为UI数据不会存储在bean上,所以我无法访问它。从技术上讲,我可以在UI组件树中找到数据,但遍历它似乎不是一个好主意。 从

我有一个非常复杂的表单,有很多输入和验证器。对于用户来说,这需要相当长的时间(甚至超过一个小时)才能完成,因此他们希望能够保存草稿数据,即使它违反了规则,如未键入必填字段

我相信这个问题在许多web应用程序中都很常见,但找不到任何公认的模式来实现它。你能告诉我如何做到这一点吗

目前,我可以看到以下选项:

  • 在“保存草稿”按钮上使用immediate=true不起作用,因为UI数据不会存储在bean上,所以我无法访问它。从技术上讲,我可以在UI组件树中找到数据,但遍历它似乎不是一个好主意。
  • 从页面中删除所有验证字段,并验证为表单定义的操作侦听器中的数据ProgramMaticali。同样,这不是一个好主意,表单非常复杂,有很多字段,因此以这种方式实现的验证将非常混乱。
  • 实现我自己的验证器,它将由一些请求属性控制,这些属性将被设置为标准表单提交(需要完全验证),并且将被取消设置为“另存为草稿”提交(当验证应该被跳过时)。同样,这不是一个好的解决方案,我需要为我正在使用的所有验证器提供我自己的包装。

  • 但正如你所见,没有人是真正理性的。这个问题真的没有简单的解决办法吗?

    确实没有那么容易。验证在JSF生命周期中是紧密耦合的

    我个人会选择选项1。没错,这是一项肮脏的工作,但您可以将其隐藏在实用程序类中。只需从viewroot中抓取有问题的
    ,递归地迭代其子级,从而测试EditableValueHolder的
    组件实例是否为true,将找到的id值对存储在
    映射的排序中,最后将其持久化

    作为第四种选择,您可以使用ajaxical Power独立保存所有数据。在这方面很有帮助

    $.post('/savedraft', $('#formid').serialize());
    
    它只需要客户端的Javascript支持



    更新:JSF实用程序库有一个标记处理程序,用于确切的用途。这确实不是一个简单的解决方案,因为它还需要一个定制的
    。它通过在验证和更新模型值阶段提供一个自定义的
    FacesContext
    实例来完成其工作,该实例在
    validationFailed()
    renderResponse()方法中执行NOOP。因此组件仍然是无效的,消息仍然是附加的,但它仍然会进入更新模型值和调用应用程序阶段。

    我也有同样的问题,我不喜欢跳过所有验证的想法。经过深思熟虑,我最终只想跳过必填字段验证。这背后的逻辑是用户要么正确地填写字段,要么根本不填写。这对我来说非常重要,因为所有内容最终都在数据库中,当然,我不希望数据库字段溢出,或者最终将
    String
    值保存到
    INT
    数据库字段中

    根据我的经验,跳过必填字段允许有足够的机动余地来保存草稿。为了实现这一点,我最终编写了一个显示单个警告消息的
    requiredWarnValidator

    public void validate(FacesContext context, UIComponent component, Object value)
        throws ValidatorException {
    
      if (value == null) {
        FacesMessage message = new FacesMessage();
        message.setSeverity(FacesMessage.SEVERITY_WARN);
        message.setSummary("This field is required.");
        context.addMessage(component.getClientId(), message);
        context.validationFailed();
      }
    }
    
    在这个验证器中,我不会抛出一个
    ValidatorException()
    ,因为我想通过验证阶段,但我调用
    validationFailed()
    ,因为我想知道是否有必填字段没有填写

    我在用于保存表单的实体中有一个标志(
    已完成
    )。保存表单时,我选中了
    isValidationFailed()

    • 如果
      true
      至少有一个必填字段未填写:我取消选中标志
      completed
      。(这是一份草稿)
    • 如果
      false
      所有表单都已完成:我检查标志
      completed
      。(这不是草案)
    这也允许我有一个“保存”按钮,而不是两个按钮(“保存”和“另存为草稿”)

    注意事项和已知陷阱:

    • 如果要将草稿保存到数据库,则必须确保没有
      notnull
      约束
    • 使用转换器和验证器时,必须确保它们能够处理
      NULL
    • 您将丢失字段的
      outputLabel
      中所需的字段星号

    谢谢你,巴卢斯。我喜欢您对选项1的想法,当同相侦听器加载数据并重新初始化EditableValueHolders时,我可能会做相反的事情。关于您的第二个建议,我在jQuery中找不到任何unserialize()函数,您将如何加载草稿数据?通过在服务器端相应地设置托管bean属性。