【问题标题】:View keeps older value when I clear my backing bean当我清除我的支持 bean 时,视图保持旧值
【发布时间】:2013-02-17 11:38:09
【问题描述】:

JSF 值绑定是单向的还是双向的?

当我清除我的支持 bean 数据时,视图仍然保留旧值。 这是 JSF 的工作方式吗? 我想知道一种将视图与支持 bean 同步的方法。

【问题讨论】:

    标签: jsf jsf-2 el


    【解决方案1】:

    JSF 做你告诉它做的事情。

    为了刷新视图(在对 bean 进行一些更改之后),您需要通过从您的操作方法返回 null/void 来执行 回发到原始视图,或者指定要执行(更新)和稍后呈现(刷新)为 <f:ajax> 标签的属性 附加到应该更改的组件的客户端 ID(或其他可接受的值,如 @form)你的豆子。

    【讨论】:

      【解决方案2】:

      是的,数据绑定是双向的。但是,如果不回答两个关键问题,这意味着什么:

      • 当读写发生时,
      • 发生在什么条件下。

      答案是:

      • 如果每个组件都有效,数据会在回发后从控件推送到 bean。
      • 数据是在渲染之前从 bean 读取的,即在每个操作发生并触发每个标准事件(命令按钮、值更改事件等)之后。

      这意味着与第一直觉相反: - 像输入这样的组件确实保持它们的状态,并且它与支持 bean 分离。它可以保存很长时间,甚至是多次回发,而无需与支持 bean 进行任何同步(例如,当表单上的任何其他组件无法验证时)。

      想象生命周期的最简单方法是:

      1. 组件使用请求数据和可能的其他一些与配置相关的方式来恢复其状态[仅限回发]
      2. 如果转换和验证正常,则使用绑定将来自组件的数据复制到支持 bean,如果不是,则跳过下一步,但组件仍会记住它们的状态 [仅限回发]
      3. 动作被执行(查看动作、命令)。在这个阶段,您总是可以从 bean 中读取数据并确保它是有效的(不是“连贯的”,更像是“每个单独的组件都有一个可接受的值”)。您还可以更改 bean 中的值,以确保它们将在下一步中使用。
      4. 组件使用绑定从支持 bean 中提取数据并将其提取。

      要点是:

      • 如果您尝试将任何逻辑放入 getter 和 setter 中,您就会遇到问题。如果您的任何 setter 设置了一些额外的属性,您最终会得到设置其他值的代码,结果可能取决于调用绑定的顺序(第 2 步);
      • 更改任何数据的唯一好时机是第 3 步:执行操作的那一刻;
      • 如果您没有任何操作,您也可以使用 PreRenderView 事件,它在步骤 3 和步骤 4 之间被调用(如果您有一个纯 GET 页面,则可用于将一些数据移动到 bean 中,没有回发)。
      • 在转换器、验证器和 valuechangelistener 中更改 bean 或依赖 bean 的值 - 至少很棘手。

      如果您尝试将 JSF 与谷物一起使用,那么使用起来真的很愉快。如果试图违背常规并将 JSF 转变为您对 Web 框架应该如何工作的想法(例如在验证器中使用业务验证、更改转换器内部的模型、从构造函数读取数据库等),您将需要 BalusC 的大量帮助:-)

      【讨论】:

      • 请注意,如果属性在提交的表单中,绑定将是双向的,否则 JSF 将仅使用 getter。
      • @LuiggiMendoza:不要忘记服务器需要被插入!电力对于 JavaServer Faces 的工作至关重要。
      • 电力对您的电子设备充电、登录 SO 并添加此类 cmets 也是至关重要的!
      【解决方案3】:

      不太确定您要问什么,但是是的,如果您的 bean 不是请求范围,它们将使用以前的值填充您的 html 表单控件。

      如果您的 bean 是视图范围或会话范围,您仍然可以通过在 bean 的操作方法(commandLink/commanButton 操作)中操作模型值来控制呈现的值

      如果您希望在以后访问同一页面时清除这些值,您应该让您的页面 bean 请求范围。

      如果您愿意,您可以通过使用绑定而不是值直接对 UIComponents 进行微管理以实现完全控制,从而允许您直接在 bean 中创建和管理 UIComponents。例如

      <h:inputText binding="#{bean.inputComponent" /> 并在您的代码中

      public class myBean {
          private UIInput inputComponent;
      
          public UIComponent getInputComponent() {
              // create your UIComponent here, and manage values in your command methods
          }
      
          public void setInputComponent(UIComponent component) {
               inputComponent = component;
          }
      

      }

      【讨论】:

      • 这不太正确。请求范围的 bean 将被重新创建,并在下一次请求时重新填充(使用客户端值),尽管不会重新创建视图范围的 bean,而是从视图中恢复(不包括鸡蛋)。但数据将保持不变。
      • 啊,是的,我明白了你的意思,我编辑了我的答案以更清晰 - 但如果你希望也可以通过在你的操作方法中返回相同的 viewid 来完全重置视图 - 请参阅stackoverflow.com/questions/9458911/…示例
      • 当然,因为它不会是回发。但我理解 OP 的问题,即他希望他在(侦听器)方法之一中产生的更改反映在他的观点中。顺便问一下,你知道 UI 组件的 binding 属性对 view scoped beans 有什么作用吗?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-03-10
      • 2015-11-03
      • 2012-04-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多