【问题标题】:JSF2 - what scope for f:ajax elements?JSF2 - f:ajax 元素的范围是什么?
【发布时间】:2011-01-30 23:08:12
【问题描述】:

我有这个表格:

<h:form>
    <h:outputText value="Tag:" />   
    <h:inputText value="#{entryRecorder.tag}">
        <f:ajax render="category" />
    </h:inputText>
    <h:outputText value="Category:" />
    <h:inputText value="#{entryRecorder.category}" id="category" />
</h:form>

我想要实现的目标:当您在“标签”字段中键入时,entryRecorder.tag 字段会更新为键入的内容。根据这个动作的一些逻辑,bean 也会更新它的category 字段。这种变化应该反映在表单中。

问题:

  1. EntryRecorder 应该使用什么范围?请求可能无法满足多个 AJAX 请求,而会话将无法在一个会话中使用多个浏览器窗口。
  2. 如何在EntryRecorder 中注册我的updateCategory() 操作,以便在更新bean 时触发它?

【问题讨论】:

  • 我会使用 ViewScoped,但我真的很想看看是否有人对第 1 点有更多要说的。

标签: ajax jsf-2


【解决方案1】:

回答点2:

<h:inputText styleClass="id_tag" value="#{entryRecorder.tag}"
    valueChangeListener="#{entryRecorder.tagUpdated}">
    <f:ajax render="category" event="blur" />
</h:inputText>

豆子:

@ManagedBean
@ViewScoped
public class EntryRecorder {
    private String tag;
    private String category;
    @EJB
    private ExpenseService expenseService;

    public void tagUpdated(ValueChangeEvent e) {
        String value = (String) e.getNewValue();
        setCategory(expenseService.getCategory(value));
    }
}

1 号,有人吗?

【讨论】:

    【解决方案2】:

    对于第 1 点,我将使用 Request,因为不需要使用 View,而 Session 正如您所指出的,完全没有必要。

    对于第 2 点,由于您使用的是 ,我建议充分利用它。这是我的建议:

    xhtml:

    <h:form>
        <h:outputText value="Tag:" />
        <h:inputText value="#{entryRecorder.tag}">
            <f:ajax render="category" event="valueChange"/>
        </h:inputText>
        <h:outputText value="Category:" />
        <h:inputText value="#{entryRecorder.category}" id="category" />
    </h:form>
    

    注意使用 valueChange 事件而不是 blur(并不是说 blur 不起作用,但我发现 valueChange 对于值持有者组件更“合适”)。

    豆子:

    @ManagedBean
    @RequestScoped
    public class EntryRecorder {
        private String tag;
        private String category;
    
        public String getCategory() {
            return category;
        }
    
        public String getTag() {
            return tag;
        }
    
        public void setCategory(String category) {
            this.category = category;
        }
    
        public void setTag(String tag) {
            this.tag = tag;
            tagUpdated();
        }
    
        private void tagUpdated() {
            category = tag;
        }
    }
    

    除非您真的希望 tagUpdated 方法仅在通过视图更新标签时执行,否则我的建议看起来更清晰。您不必处理事件(也不必进行转换),并且 tagUpdated 方法可以是私有的,隐藏它的功能以防止可能的误用。

    【讨论】:

    • 如果这个bean由于某种原因很重,请求范围方法似乎不是最佳的。
    • “如果这个 bean 出于某种原因很重,那么请求范围方法似乎不是最佳的。” - 的确。如果您有一个非常重的 bean,您应该考虑将其拆分,甚至将标签类别输入封装到自定义组件中,而不是仅仅因为它使您的应用程序运行更顺畅而更改 bean 的范围(您是否运行了一些性能测试?)而不是因为它有意义。
    猜你喜欢
    • 1970-01-01
    • 2014-05-20
    • 1970-01-01
    • 2012-01-02
    • 2011-11-11
    • 2020-10-18
    • 2017-04-22
    • 1970-01-01
    • 2023-03-17
    相关资源
    最近更新 更多