【问题标题】:Confusion JSF Updating Value of Input text in Backing bean支持bean中输入文本的混淆JSF更新值
【发布时间】:2014-03-20 08:13:34
【问题描述】:

今天,我正在解决 JSF 中的一个小问题。实际上,我的xhtml 页面上有一个InputTextreadyOnly 属性设置为true。要求是单击布尔值checkbox,我应该使输入文本可编辑,这意味着readyOnly false。代码有点像这样。

  <div class="div-form-col" >
            <h:outputLabel value="#{msgs.violationAmount} " for="violationAmt" />

      <h:inputText value="#{outpassMBean.violationWebDTO.violationAmount}" id="violationAmt" readonly="true"/>

    </div>

<div class="div-form-row">
                      <div class="div-form-col">
                          <h:outputLabel value="#{msgs.violationExemptionApplicable} " for="violationExempted" />
                          <h:selectBooleanCheckbox value="#{outpassMBean.violationWebDTO.violationExemptionApplicable}" id="violationExempted" onchange="makeViolationAmountEditable(this);">
                          </h:selectBooleanCheckbox>

                      </div>
                  </div>

该方法的脚本如下:-

function makeViolationAmountEditable(id){
  alert("Ben");
  document.getElementById('violationAmt' ).readOnly=false;
  alert("Done");
}

现在我的第一个问题是,如果我正在编辑文本字段中的值,我如何更新 backing bean 中的violationAmt 值。什么是最好的方法?当我使用 PrimeFaces 时,我遇到了 remoteCommand 概念。所以这是我添加的内容。

<p:remoteCommand name="makeViolationAmountEditableOnServer" action="#{outpassMBean.makeViolationAmountEditable}" update="amountPanelApplicant"/>

backing bean 级别的方法是这样的

public void makeViolationAmountEditable(){
//Set updated value 
setUpdatedViolationAmount(violationWebDTO.getViolationAmount());
//Some other code.
}

问题是,每当运行此代码时,违规WebDTO 中的违规量是旧的,而不是我在使输入字段可编辑后输入的量。尽管我在萤火虫中看到更新的值是请求的一部分,但在支持 bean 中,但是仍然引用了旧值。我不明白为什么?

我的前辈告诉我,您正在客户端而不是服务器端更新 readOnly 的值,并更新了我的代码类似这样。

<p:outputPanel id="amountPanelApplicant">
          <p:outputPanel  rendered="#{outpassMBean.violationWebDTO.violationForCmb eq 2 and outpassMBean.violationWebDTO.isViolationExists}">
              <p:outputPanel styleClass="div-form twoCol">
                  <div class="div-form-row">
                      <div class="div-form-col" >
                          <h:outputLabel value="#{msgs.violationAmount} " for="violationAmt" />

                          <h:inputText value="#{outpassMBean.violationWebDTO.violationAmount}" id="violationAmt" readonly="#{outpassMBean.violationAmtEditable}">

                          </h:inputText>

                      </div>

                      <div class="div-form-col">
                          <h:outputLabel value="#{msgs.outPayTot} " for="totalViolationAmount" />
                          <h:outputLabel styleClass="readOnly" value="#{outpassMBean.violationWebDTO.totalViolationAmount}" id="totalViolationAmount" />
                      </div>
                  </div>

              </p:outputPanel>

              <p:outputPanel styleClass="div-form twoCol" rendered="#{outpassMBean.outpassApplication.applicationSubType.id eq 2 }" >
                  <div class="div-form-row">
                      <div class="div-form-col">
                          <h:outputLabel value="#{msgs.violationExemptionApplicable} " for="violationExempted" />
                          <h:selectBooleanCheckbox value="#{outpassMBean.violationWebDTO.violationExemptionApplicable}" id="violationExempted" onchange="makeViolationAmountEditableOnServer();">
                          </h:selectBooleanCheckbox>
                          <p:remoteCommand name="makeViolationAmountEditableOnServer" action="#{outpassMBean.makeViolationAmountEditable}" update="amountPanelApplicant"/>

                      </div>
                  </div>
              </p:outputPanel>
</p:outputPanel>

public void makeViolationAmountEditable(){
    if(logger.isDebugEnabled()){
      logger.debug("Inside makeViolationAmountEditable...");
    }
    //setting violation amount editable flag
    setViolationAmtEditable(false);

    //Preserving original and total amount.
    setOriginalViolationAmt(violationWebDTO.getViolationAmount());
    setOriginalTotalViolationAmount(violationWebDTO.getTotalViolationAmount());

  }

在上面更新的代码中,没有调用 javascript。 readyOnly 值从支持 bean 本身设置为 true 和 false。这次更新之后,基本上新的编辑值在violationWebDTO中更新了。

谁能解释一下?为什么不在第一个快照中?这不是一个完整的代码,但我试图解释混乱。任何指针都会有所帮助。

【问题讨论】:

  • 在以后的问题中,请尝试发布相关代码。当然,当您删除那些&lt;div&gt;&lt;h:outputLabel&gt; 等标签时,问题并没有消失。那就让他们出去吧!
  • @BalusC,我肯定会使用您提供的指南。我只是理解答案,如果我发现更多困惑,我会更新你。

标签: jsf primefaces


【解决方案1】:

这是 JSF 对被篡改/黑客请求的保护措施,其中最终用户使用客户端语言/工具(如 HTML 或 JS)来操作 HTML DOM 树和/或 HTTP 请求参数,从而使 JSF 的disabled、@ 987654326@ 甚至 rendered 属性被更改。

想象一下,如果 JSF 开发人员在这样的布尔属性中检查用户的角色与管理员角色(如 disabled="#{not user.hasRole('ADMIN')}"),并且黑客以这样的方式操纵它,使其不再对非管理员用户禁用,会发生什么情况。这就是为什么您只能在服务器端更改上述属性(以及 required 属性和所有转换器、验证器、事件侦听器等)。

但是,这可以通过更简单的方式解决,无需额外的属性,无需 &lt;p:remoteCommand&gt; 和额外的 bean 方法。

<h:inputText id="violationAmount" ... readonly="#{makeViolationAmountEditable.value}" />
...
<h:selectBooleanCheckbox binding="#{makeViolationAmountEditable}">
    <f:ajax render="violationAmount" />
</h:selectBooleanCheckbox>

另见:

【讨论】:

  • 我有点困惑,当你说 readonly="#{makeViolationAmountEditable.value}" 时,你是在调用 backing bean 方法吗?这个值指的是什么?是否绑定属性,将布尔复选框绑定到支持 bean 方法?
  • 这在第二个“另见”链接中有详细说明
  • 另一个相关答案,对带有绑定的复选框有更具体的解释:stackoverflow.com/questions/17167377/jsf-checkbox-listener/…
  • 1) 在那里你使用组件的value 属性。 2) 对不起? &lt;f:ajax&gt; 也是对你来说是新的吗?我知道binding 是最不了解的功能,通常不会深入解释,但&lt;f:ajax&gt; 应该已经在一本理智的 JSF2 书籍/教程的第一章中介绍过。它只是在默认的 HTML DOM 事件上触发一个 ajax 请求,render 属性告诉 JSF 在响应中重新渲染(更新)哪些组件。这样,复选框组件的值将在 readonly 属性中重新评估。
  • 换句话说,您甚至没有尝试过给定的代码?和我的回答一样,代码是完整的和原样的。你不只是对它的简单感到惊讶吗?它的工作原理已经在给定的链接中进行了深入解释。要继续上一个给定的链接,“视图构建时间”与“视图渲染时间”依次深入解释 stackoverflow.com/a/3343681
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-26
  • 1970-01-01
  • 1970-01-01
  • 2013-01-17
  • 1970-01-01
相关资源
最近更新 更多