【问题标题】:a4j:jsFunction with actionListener inside of h:dataTablea4j:jsFunction 与 h:dataTable 内的 actionListener
【发布时间】:2011-01-29 00:40:07
【问题描述】:

我在使用 a4j:jsFunction 和 h:dataTable 内的 actionListener 时遇到问题,当我想使用 a4j:commandLink 对特定行调用操作时,它可以正常工作,但是当我想使用 a4j:jsFunction 调用操作时& actionListener 它总是在 dataTable 中的最后一个元素上调用 举个例子吧:

    <a4j:form ajaxSubmit="true" reRender="mainForm" id="mainForm">
        <a4j:region>
            <t:saveState value="#{ts.list}" />
        </a4j:region>

        <h:dataTable value="#{ts.list}" var="el" binding="#{ts.bind}">
        <h:column>#{el}</h:column>>
        <h:column>
            <a4j:commandLink actionListener="#{ts.rem}">
                    <h:outputText value="delete by CMDLink" />
                </a4j:commandLink>
            </h:column>
        <h:column>
                <a href="#" onclick="okClicked();">delete by okClicked</a>
                <a4j:jsFunction name="okClicked"
                    actionListener="#{ts.rem}"
                />
        </h:column>
   </h:dataTable>
    </a4j:form>

现在,bean 的代码:

package com.sth;

import java.util.ArrayList;
import java.util.List;

import javax.faces.component.UIData;
import javax.faces.event.ActionEvent;

public class Ts {

    private List<String> list = new ArrayList<String>();
    private UIData bind;

    public Ts(){
        list.add("element1");
        list.add("element2");
        list.add("element3");
        list.add("element4");
    }

    public List<String> getList() {
        return list;
    }

    public void setList(List<String> list) {
        this.list = list;
    }

    public void rem(ActionEvent ae) {
        String toRem = (String) bind.getRowData();
        System.out.println("Deleting " + toRem);
        list.remove(toRem);
    }

    public UIData getBind() {
        return bind;
    }

    public void setBind(UIData bind) {
        this.bind = bind;
    }

}

当我使用 a4j:commandLink 删除元素时,它按预期工作,但是当我使用 a4j:jsFunction 调用 actionListener 时,它会针对最后一个元素调用动作:( 有任何想法吗? 干杯

【问题讨论】:

  • 有什么理由比a4j:commandLink更喜欢a4j:jsFunction
  • 我想用 jQuery 做“模态确认框”,所以 jQuery 对话框会从 jsFunction 触发 okClicked()

标签: javascript jsf datatable


【解决方案1】:

您可以通过将 控件中移出

来实现您的目标

这是一个例子

 <a4j:form ajaxSubmit="true" reRender="mainForm" id="mainForm">

    <h:dataTable value="#{ts.list}" var="el" binding="#{ts.bind}">
      <h:column>#{el}</h:column>>
      <h:column>
            <a4j:commandButton 
                onclick="#{rich:component
                     ('confirmation')}.show();return false">Delete</a4j:commandButton>
      </h:column>
    </h:dataTable>
    <a4j:jsFunction name="remove" action="#{ts.remove(el)}" reRender="mainForm"/>
 </a4j:form>

确认对话框:

<rich:modalPanel id="confirmation" width="250" height="150">
        <f:facet name="header">
            <h:panelGrid columns="2">
                <h:graphicImage value="/img/delete.gif"/>
                <h:outputText value="Confirmation"/>
            </h:panelGrid>
        </f:facet>
        <h:panelGrid style="height: 100%">
            <h:panelGrid columns="2" cellpadding="5px">
                <h:graphicImage value="/img/error_large.gif"/>
                <h:outputText value="Delete ?" style="font-size: large;"/>
            </h:panelGrid>
            <h:panelGroup style="margin-top: 20px">
                <input type="button" value="Yes" style="width: 100px"
                       onclick="#{rich:component('confirmation')}.hide();remove();return false"/>
                <input type="button" value="No" style="width: 100px"
                       onclick="#{rich:component('confirmation')}.hide();return false"/>
            </h:panelGroup>
        </h:panelGrid>
    </rich:modalPanel>

【讨论】:

    【解决方案2】:

    根据 cmets,事实证明您只想触发确认对话。您也可以为此使用a4j:commandLink,在onclick 属性中调用它并让它返回true 或false 以允许或阻止操作。这是一个启动示例,就像您使用标准确认对话框一样:

    <a4j:commandLink onclick="return confirm('Are you sure?');">
    

    这样您就不需要花几个小时来挣扎/调试奇怪的a4j:jsFunction 行为。

    【讨论】:

    • 感谢 BalusC 的回复 :-) 我已经使用过这个解决方案,我想使用 jQuery 对话框来实现“眼睛友好”,但似乎没有简单的解决方案
    • 是的,我知道。这只是一个启动示例。用您的 jQuery 函数替换 confirm()。重点是让它返回 true 或 false 以阻止默认链接操作。
    • 不幸的是 jQuery 对话框不能以这种方式工作,几周前我遇到了同样的问题:stackoverflow.com/questions/1812500/…
    【解决方案3】:

    据我了解,使用 a4j:jsFunction 标签:

    <a4j:jsFunction name="okClicked" actionListener="#{ts.rem}" />
    

    被放置在数据表的列中,一个名为okClicked 的JavaScript 函数将被添加到表中每一行的列中的HTML 页面中。由于名称相同,每个 JavaScript 函数都会覆盖前一个函数的定义,因此在调用 okClicked() 时,实际上只执行最后定义的函数。这就是为什么要调用 actionListener 来调用“针对最后一个元素的操作”的原因。

    解决此问题的一种方法是将行索引作为 a4j:jsFunction 标记创建的 JavaScript 函数名称的一部分:

    <h:dataTable value="#{ts.list}" var="el" binding="#{ts.bind}" rowIndexVar="index">
        <h:column>
            <a href="#" onclick="okClicked#{index}();">delete by okClicked</a>
            <a4j:jsFunction name="okClicked#{index}" actionListener="#{ts.rem}"/>
        </h:column>
    </h:datatable>
    

    我还没有测试过上面的解决方案(我不知道将#{ts.rem}绑定到JS函数actionListener而不是将其绑定到commandLinkactionListener是否会有问题)但是如果onClick 的值 okClicked#{index}(); 不能直接工作,而是调用一个 javaScript 函数,该函数从索引值构建的字符串创建函数名称:

    function onClicked(row) {
        functionStr = "okClicked" + row;
        window[functionStr]();
    }
    

    我不得不使用类似的东西,需要在数据表中使用“jsFunction”网格,在该数据表中,我需要处理多列和多行。

    希望这对将来的其他人有用。

    【讨论】:

      猜你喜欢
      • 2016-03-26
      • 1970-01-01
      • 2011-02-23
      • 1970-01-01
      • 2018-05-24
      • 2016-11-25
      • 2012-05-24
      • 1970-01-01
      • 2013-05-11
      相关资源
      最近更新 更多