使用 PrimeFaces DF 打开多个对话框
Opening multiple dialogs with PrimeFaces DF
使用 PrimeFaces,我想打开多个不同的对话框。乍一看,一个简单的方法似乎是 PrimeFaces Dialog Framework。哪个在一定程度上起作用。
我有一个DataTable
有记录,每条记录都可以开成一条新的Dialog
。对于每条记录,打开此对话框都可以正常工作。但似乎 Dialog
似乎绑定到其调用父级的 ID。
下面是一个演示此问题的最小示例。考虑以下 xhtml
.
<h:form id="indexForm">
<p:dataTable id="indexTable" value="#{dFDemo.indexes}" var="index">
<p:column sortBy="#{index}" headerText="index">
<p:commandButton id="openDialogBtn" value="Open dialog #{index}"
action="#{dFDemo.openDialog(index)}"/>
</p:column>
</p:dataTable>
</h:form>
以及以下辅助 bean:
@ManagedBean
public class DFDemo {
private List<Integer> indexes = Arrays.asList(1, 2, 3, 4, 5);
public void openDialog(int index) {
System.out.println("Opening a dialog for " + index);
PrimeFaces.current().dialog().openDynamic("dfdemo", null, null);
}
// Getter & Setter
}
如果我点击第一个按钮,它会打开一个对话框并打印 Opening a dialog for 1
。同样,如果我单击第二个按钮,它会打开另一个对话框并打印 Opening a dialog for 2
.
按钮 1 和 2 现在不能再打开新对话框。它会在服务器上调用 openDynamic()
,但不会打开任何内容。我认为它链接到其父级的原因是,如果您更改排序顺序并将索引 5 放在顶部,您仍然无法单击第一行(现在是按钮 5)。
我认为这是因为它链接到 rowIndex
以确保唯一 ID。我可以看到该按钮已使用 onclick='PrimeFaces.ab({s:"indexForm:indexTable:0:openDialogBtn"});return false;'
.
重新呈现
不过我打算重新加载这个 table。这个table的内容会不一样,但是这个table的ID不会变。无法打开新对话框。
我尝试附加一些随机 ID 以确保在重新呈现 table 时的唯一性。但是附加我自己的 id 会导致组件中断(排序、操作...)。
我也无法使用具有特定区域更新的常规 Dialog
组件。因为它会破坏现有对话框的生命周期。
这似乎是对话框框架的默认行为。正如在 Dialog Framework showcase 中一样,无法从同一个按钮打开多个对话框。
是否可以让 Dialog Framework 从同一来源打开多个对话框,或者是否有解决此问题的方法?
要让 Dialog Framework
发挥作用,您需要注册适当的 ActionListener
。配置的默认 ActionListener
是 org.primefaces.application.DialogActionListener
。在这个ActionListener
中,源WidgetVar
和源ClientId
被放入FacesContext
.
在我的例子中,提供一个将随机 UUID 作为源组件的自定义实现就足够了。这允许从激活 Dialog
.
的按钮打开多个对话框
所以下面的监听器:
public class RandomSourceDialogActionListener implements ActionListener {
private ActionListener base;
public RandomSourceDialogActionListener(ActionListener base) {
this.base = base;
}
@Override
public void processAction(ActionEvent event) throws AbortProcessingException {
Map<Object, Object> attrs = FacesContext.getCurrentInstance().getAttributes();
attrs.put(Constants.DIALOG_FRAMEWORK.SOURCE_COMPONENT, UUID.randomUUID().toString());
base.processAction(event);
}
}
注册于faces-config.xml
:
<application>
<action-listener>my.application.RandomSourceDialogActionListener</action-listener>
<navigation-handler>org.primefaces.application.DialogNavigationHandler</navigation-handler>
<view-handler>org.primefaces.application.DialogViewHandler</view-handler>
</application>
注意:由于源组件不再为人所知,源组件不再正确处理dialogReturn
等事件。另一方面,原来的 DialogActionHandler
似乎也没有在 DataTable
中处理这些事件。但是当只使用一个按钮时它可能会影响你。
使用 PrimeFaces,我想打开多个不同的对话框。乍一看,一个简单的方法似乎是 PrimeFaces Dialog Framework。哪个在一定程度上起作用。
我有一个DataTable
有记录,每条记录都可以开成一条新的Dialog
。对于每条记录,打开此对话框都可以正常工作。但似乎 Dialog
似乎绑定到其调用父级的 ID。
下面是一个演示此问题的最小示例。考虑以下 xhtml
.
<h:form id="indexForm">
<p:dataTable id="indexTable" value="#{dFDemo.indexes}" var="index">
<p:column sortBy="#{index}" headerText="index">
<p:commandButton id="openDialogBtn" value="Open dialog #{index}"
action="#{dFDemo.openDialog(index)}"/>
</p:column>
</p:dataTable>
</h:form>
以及以下辅助 bean:
@ManagedBean
public class DFDemo {
private List<Integer> indexes = Arrays.asList(1, 2, 3, 4, 5);
public void openDialog(int index) {
System.out.println("Opening a dialog for " + index);
PrimeFaces.current().dialog().openDynamic("dfdemo", null, null);
}
// Getter & Setter
}
如果我点击第一个按钮,它会打开一个对话框并打印 Opening a dialog for 1
。同样,如果我单击第二个按钮,它会打开另一个对话框并打印 Opening a dialog for 2
.
按钮 1 和 2 现在不能再打开新对话框。它会在服务器上调用 openDynamic()
,但不会打开任何内容。我认为它链接到其父级的原因是,如果您更改排序顺序并将索引 5 放在顶部,您仍然无法单击第一行(现在是按钮 5)。
我认为这是因为它链接到 rowIndex
以确保唯一 ID。我可以看到该按钮已使用 onclick='PrimeFaces.ab({s:"indexForm:indexTable:0:openDialogBtn"});return false;'
.
不过我打算重新加载这个 table。这个table的内容会不一样,但是这个table的ID不会变。无法打开新对话框。
我尝试附加一些随机 ID 以确保在重新呈现 table 时的唯一性。但是附加我自己的 id 会导致组件中断(排序、操作...)。
我也无法使用具有特定区域更新的常规 Dialog
组件。因为它会破坏现有对话框的生命周期。
这似乎是对话框框架的默认行为。正如在 Dialog Framework showcase 中一样,无法从同一个按钮打开多个对话框。
是否可以让 Dialog Framework 从同一来源打开多个对话框,或者是否有解决此问题的方法?
要让 Dialog Framework
发挥作用,您需要注册适当的 ActionListener
。配置的默认 ActionListener
是 org.primefaces.application.DialogActionListener
。在这个ActionListener
中,源WidgetVar
和源ClientId
被放入FacesContext
.
在我的例子中,提供一个将随机 UUID 作为源组件的自定义实现就足够了。这允许从激活 Dialog
.
所以下面的监听器:
public class RandomSourceDialogActionListener implements ActionListener {
private ActionListener base;
public RandomSourceDialogActionListener(ActionListener base) {
this.base = base;
}
@Override
public void processAction(ActionEvent event) throws AbortProcessingException {
Map<Object, Object> attrs = FacesContext.getCurrentInstance().getAttributes();
attrs.put(Constants.DIALOG_FRAMEWORK.SOURCE_COMPONENT, UUID.randomUUID().toString());
base.processAction(event);
}
}
注册于faces-config.xml
:
<application>
<action-listener>my.application.RandomSourceDialogActionListener</action-listener>
<navigation-handler>org.primefaces.application.DialogNavigationHandler</navigation-handler>
<view-handler>org.primefaces.application.DialogViewHandler</view-handler>
</application>
注意:由于源组件不再为人所知,源组件不再正确处理dialogReturn
等事件。另一方面,原来的 DialogActionHandler
似乎也没有在 DataTable
中处理这些事件。但是当只使用一个按钮时它可能会影响你。