JSF中的数据选择器组件

时间:2017-10-03 04:22:40

标签: jsf primefaces

我正在尝试开发可重用的数据选择器。它将用于查找相关数据并在托管bean属性中设置。

我试图改变的是这样的:

1)带有输入文本和查找按钮的复合词:

enter image description here

2)当用户点击搜索按钮时,它会打开一个新页面。

3)此页面允许搜索特定记录

4)一旦找到,用户点击一个按钮并选择它

enter image description here

5)当用户点击检查按钮(上表中的最后一列)时,它会设置绑定到输入的字段中的值(#1)。

搜索始终在同一实体中完成,因为它是此类实体的数据选择器,但目标未知,因为它是可重用的组件。

如何在搜索结果,用户选择的内容和目标对象(托管bean的属性)之间建立连接?

我不知道如何继续。

提前致谢,

修改

更多信息:经过一番研究后,我发现了一种传递托管bean和property / actionListener的方法。我将解释我的所作所为,然后描述现在的问题。

1)创建了一个示例页面(sample1.xhtml)。它是一个组合/片段:

    <?xml version='1.0' encoding='UTF-8' ?>
    <!DOCTYPE html>
    <ui:fragment xmlns="http://www.w3.org/1999/xhtml"
        xmlns:h="http://java.sun.com/jsf/html"
        xmlns:c="http://java.sun.com/jsp/jstl/core"
        xmlns:b="http://bootsfaces.net/ui"
        xmlns:ui="http://java.sun.com/jsf/facelets"
        xmlns:f="http://java.sun.com/jsf/core"
        xmlns:p="http://primefaces.org/ui"
        xmlns:bt="http://xmlns.jcp.org/jsf/composite/tags/bt"
        xmlns:pt="http://xmlns.jcp.org/jsf/passthrough">

        <ui:composition template="/templates/pages/form.xhtml">
            <ui:param name="title" value="Manage Value Object Category" />
            <ui:define name="toolbar">
            </ui:define>
            <ui:define name="form-fields">
                <c:set var="variable" value="#{valueObjectBean}" scope="request" />
                <p:commandButton actionListener="#{valueObjectBean.doTest()}"
                    value="test" update="@form" />
            </ui:define>
            <ui:define name="bar-cmd">
            </ui:define>
        </ui:composition>

    </ui:fragment>

请注意:

a)c:将set设置为要调用的托管bean的请求范围变量。

b)valueObjectBean.doTest()只是替换要显示的组合。

2)这是目标网页:

            <?xml version='1.0' encoding='UTF-8' ?>
    <!DOCTYPE html>
    <ui:fragment xmlns="http://www.w3.org/1999/xhtml"
        xmlns:h="http://java.sun.com/jsf/html"
        xmlns:c="http://java.sun.com/jsp/jstl/core"
        xmlns:b="http://bootsfaces.net/ui"
        xmlns:ui="http://java.sun.com/jsf/facelets"
        xmlns:f="http://java.sun.com/jsf/core"
        xmlns:p="http://primefaces.org/ui"
        xmlns:bt="http://xmlns.jcp.org/jsf/composite/tags/bt"
        xmlns:pt="http://xmlns.jcp.org/jsf/passthrough">

        <ui:composition template="/templates/pages/form.xhtml">
            <ui:param name="title" value="Manage Value Object Category" />
            <ui:define name="toolbar">
            </ui:define>
            <ui:define name="form-fields">
                <h:outputText value="Hello: #{variable}" />
                <p:commandButton id="call" actionListener="#{variable['doTest'](null)}"
                    value="Execute" />

                <p:commandButton id="set" value="Set">
                    <f:setPropertyActionListener value="true"
                        target="#{variable['actAddCatItem']}"></f:setPropertyActionListener>
                </p:commandButton>
            </ui:define>
            <ui:define name="bar-cmd">
            </ui:define>
        </ui:composition>

    </ui:fragment>

请注意:

a)带有id&#34; call&#34;的commandButton从#1a中设置的托管bean调用一个动作监听器:{variable&#39; doTest&#39;}。通话方式&#39; doTest&#39;从managedBean作为变量传递给&#39;变量&#39;。

b)提一下,但现在不重要了。另一个id为&#34; set&#34;的commandButton只需将属性设置为#1a中的托管bean集。我还没有探索过这个选项。

现在,发生了什么:

1)当#c:set是请求作用域时(范围=&#34;请求&#34;),第二页&#34;看到&#34;托管bean作为参数传递:

enter image description here

a)如你所见,它输出托管bean的toString,但当我点击id为#34的命令按钮时,调用#34;,我收到此错误:

16:59:24,901 WARNING [javax.enterprise.resource.webcontainer.jsf.lifecycle] (default task-39) /WEB-INF/lib/infra-wm-1.0.jar/META-INF/resources/infra/valueobject/sample2.xhtml @24,44 target="#{variable['actAddCatItem']}": Target Unreachable, identifier 'variable' resolved to null: javax.el.PropertyNotFoundException: /WEB-INF/lib/infra-wm-1.0.jar/META-INF/resources/infra/valueobject/sample2.xhtml @24,44 target="#{variable['actAddCatItem']}": Target Unreachable, identifier 'variable' resolved to null

如果我更改c:将范围设置为&#39;查看&#39;这种方法效果很好。但我无法使用此范围,因为页面中可能有多个复合使用相同的方法(最后它是复合组件)。

现在的问题是:为什么样本2会识别变量&#39;当它是视图范围时,如果它的请求作用域虽然正确传递了值并且它不是NULL,但它没有?

谢谢,

1 个答案:

答案 0 :(得分:0)

经过一番研究后,我放弃了这种方法并通过Primeface的模态对话做了我想要完成的事情,但我对此并不满意,因为模态对话框在移动设备上效果不佳,特别是当您需要打开对话框对话框时。但问题已经解决了,至少在第一版中已经解决了。

现在我回到了挑战中并采取了另一种方法,最终效果很好。

1)找到一种方法将托管bean从一个复合体传递到另一个复合体

失败,因为在渲染时评估来自commandButton的actionListener绑定并且始终为NULL。我在这里询问并提出了最后的想法:Question

<强>解决方案:

阅读一些文章,问题,我得到了所有问题的最终答案:使用commandButton绑定以编程方式实例化组件,设置actionListener并将选定值设置为最初执行查找的实体。说明基于我的第一篇文章:

1)使用lookup commandLink进行编辑是一个简单的复合(#1)

1.1)复合界面具有设置所需的所有属性,最重要的是:

  • 将设置所选对象的值属性

  • 托管bean + actionListener从搜索结果中回调(或设置)所选对象

1.2)设置一些组件变量以避免向最终用户(开发人员)公开不必要的属性

  • 根据标准执行搜索的页面(可能是重定向到搜索页面的managedBean + actionLister

  • 表示结果dataTable(var属性名称)中的行的表达式,用于定义actionListener的回调方法表达式

2)在搜索页面(每个实体类型必须拥有它),用于选择行的commandButton(#4)是基于组件的接口和变量以编程方式创建的。声明只是<p:commandButton binding=#{dataLookupBean.bind} />

最后,允许返回上一页设置所选对象的代码:

public CommandButton getBind() {
    try {
        cb = new CommandButton();

        StringBuffer fullCommand = new StringBuffer("#{").append(bean).append(".").append(action).append("(")
                .append(paramEl).append(")").append("}");

        Class<?>[] aParamTypeClazz;

        aParamTypeClazz = new Class<?>[] { Class.forName(paramType) };
        cb.addActionListener(new MethodExpressionActionListener(
                createMethodExpression(fullCommand.toString(), aParamTypeClazz)));

        if (!BtUtil.isNullOrEmpty(buttonIcon))
            cb.setIcon(buttonIcon);

        if (!BtUtil.isNullOrEmpty(buttonValue))
            cb.setValue(buttonValue);

        return cb;
    } catch (ClassNotFoundException e) {
        log.error(e.getMessage(), e);
        throw new InfraException(e.getMessage());
    }
}

list&#34; Actions&#34;的命令按钮; (#4)必须遵守上面的代码。

现在可以很容易地在任何页面中添加带有查找的输入,只需声明如下内容:

<bt:pickerCompetency toolbarMode="true"
                            onSelectBean="reviewFormBean"
                            onSelectAction="doPickIndividualCompetency" />

打开搜索页面,搜索和选择的所有逻辑都是由底层复合代码完成的。

当然,它背后有更多的代码,但它是所有业务细节。路线图如上所述。随意问一些可能不太清楚的事情。