将动作侦听器方法作为标记文件属性传递

Posted

技术标签:

【中文标题】将动作侦听器方法作为标记文件属性传递【英文标题】:Passing an action listener method as tagfile attribute 【发布时间】:2013-12-13 02:19:48 【问题描述】:

我正在创建一个包含 primefaces 3.5 对话框的标记文件。该对话框包含一个命令按钮,该按钮使用动作侦听器进行参数化。问题是我是否可以将 actionlistener 方法作为属性传递给标记文件。

为了澄清问题,我准备了一个具有以下依赖项的测试用例(使用 maven)

<dependency>
  <groupId>org.primefaces</groupId>
  <artifactId>primefaces</artifactId>
  <version>3.5</version>
</dependency>

<dependency>
  <groupId>com.sun.faces</groupId>
  <artifactId>jsf-api</artifactId>
  <version>2.2.4</version>
</dependency>

<dependency>
  <groupId>com.sun.faces</groupId>
  <artifactId>jsf-impl</artifactId>
  <version>2.2.4</version>
</dependency>

我定义了一个标签库:

<?xml version="1.0" encoding="UTF-8"?>
<facelet-taglib version="2.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facelettaglibrary_2_0.xsd">
<namespace>http://demo.de/jsf/facelets</namespace>
<tag>
    <tag-name>DemoDialog</tag-name>
    <source>DemoDialog.xhtml</source>
</tag>  
</facelet-taglib>

DemoDialog.xhtml 是这样的:

<ui:composition 
   xmlns="http://www.w3.org/1999/xhtml"
   xmlns:h="http://java.sun.com/jsf/html"
   xmlns:ui="http://java.sun.com/jsf/facelets"
   xmlns:p="http://primefaces.org/ui"
   xmlns:c="http://java.sun.com/jsp/jstl/core">

  <c:if test="$empty dlgId">
    <c:set var="dlgId" value="$id" />
  </c:if>

  <c:if test="$empty widgetVar">
    <c:set var="widgetVar" value="testDlg" />
  </c:if>

  ABC: #okButtonActionListener

  <p:dialog id="#dlgId" header="#header" widgetVar="#widgetVar">
    <h:form id="testForm" style="width: 400px;">
      <p:panelGrid>
        <p:row>
          <p:column>        
            <p:commandButton oncomplete="#widgetVar.hide()" value="Cancel" />
          </p:column>
          <p:column>
            <p:commandButton
               actionListener="$okButtonActionListener"
               oncomplete="#widgetVar.hide()"
               value="Ok" />
          </p:column>
        </p:row>
      </p:panelGrid>
    </h:form>
  </p:dialog>
</ui:composition>

DemoDialog 标记终于在示例 xhtml 页面中使用

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:ui="http://java.sun.com/jsf/facelets"
      xmlns:p="http://primefaces.org/ui"
      xmlns:li="http://demo.de/jsf/facelets">
  <f:view contentType="text/html">
    <h:head>
      <f:facet name="first">
        <meta http-equiv="X-UA-Compatible" content="EmulateIE8" />
        <meta content='text/html; charset=UTF-8' http-equiv="Content-Type"/>
        <title>Dialog Template test</title>
      </f:facet>
    </h:head>
    <h:body>
      <h:form id="demoForm">
      <p:commandButton onclick="testDlg.show()"/>
      </h:form>
      <li:DemoDialog id="lidemo" onclick="alert('hello')" okButtonActionListener="\$dialogBean.action_listener()">
      </li:DemoDialog>
    </h:body>
  </f:view>
</html>

为了测试我通过 maven (mvn jetty:run-war) 启动码头的页面。

【问题讨论】:

请发布有效代码,否则您只是在引入红鲱鱼,并给人一种印象,即您不会担心问题的质量,因此也不会担心答案的质量。 感谢您的建议!添加了代码。 【参考方案1】:

您需要通过显式声明&lt;method-signature&gt; 将标签属性声明为.taglib.xml 中的方法表达式属性。它确实默认为值表达式。

<tag>
    <tag-name>DemoDialog</tag-name>
    <source>DemoDialog.xhtml</source>
    <attribute>
        <name>okButtonActionListener</name>
        <method-signature>void actionListener(javax.faces.event.ActionEvent)</method-signature>
    </attribute>
</tag> 

(方法名称 actionListener 完全由您选择;重要的是返回类型和参数类型,它们必须是完全限定名称)

额外的好处是,在 .taglib.xml 中明确声明标签属性可以在这些属性上启用 IDE 自动完成功能。

【讨论】:

如何在 JSF 2.0 中实现这一点? @fishbone 问题是关于 JSF 2.x 的,所以我不明白你的意思。 我以为是 JSF 2.2。如果我使用 web-facelettaglibrary_2_0.xsd,我的 IDE 会将“方法签名”标记标记为红色。将其更改为 web-facelettaglibrary_2_2.xsd 后红色标记消失。另外,它没有工作,但我认为原因是我忘记了标签属性值中“$”之前的“\”

以上是关于将动作侦听器方法作为标记文件属性传递的主要内容,如果未能解决你的问题,请参考以下文章

将 EL 方法表达式作为自定义 Facelets 标记文件的属性传递

解析字符串并将标记作为参数传递

将支持 bean 操作传递给 Facelet 标记文件

尝试将其作为对象中的属性传递时显示标记 URL 中断

监听器

我可以将哪些值传递给 f:ajax 标记的 event 属性?