Jsf 在没有JavaScript的情况下在datalist中动态设置ID
我的Primefaces接口有一个大问题。我想在列表上做一个循环,并显示一些信息+一个隐藏的编辑字段 XHTML Primefaces代码段:Jsf 在没有JavaScript的情况下在datalist中动态设置ID,jsf,primefaces,Jsf,Primefaces,我的Primefaces接口有一个大问题。我想在列表上做一个循环,并显示一些信息+一个隐藏的编辑字段 XHTML Primefaces代码段: <p:dataList value="#{datas}" var="data"> <div class="ui-g"> <div class="ui-g-3"> <h2>#{data.desc}</h2> </div> <div cla
<p:dataList value="#{datas}" var="data">
<div class="ui-g">
<div class="ui-g-3">
<h2>#{data.desc}</h2>
</div>
<div class="ui-g-3">
<p:commandButton operation="edit" disabled="#{data.isLocked()}" actionListener="#{view.edit(data)}"
style="width:120px;" update="edit_#{data.id}" />
<p:commandButton operation="delete" actionListener="#{view.delete(data.getId())}" disabled="#{data.isLocked()}"/>
</div>
</div>
<!-- works perfectly to set the id -->
<span id="edit_#{data.id}">#{data.desc} #{index}</span>
<!-- doesnt work - maybe of the rendering moment to set the id? -->
<p:panelGrid id="edit_#{data.id}" rendered="#{view.edit}">
<p:outputLabel for="desc" value="#{msg.text}" />
<p:inputText id="desc" value="#{view.selectedValue.desc}" />
</p:panelGrid>
#{data.desc}
#{data.desc}{index}
如果要编辑该div,如何设置panelGrid的动态ID以通过命令按钮单击进行更新?+如何在编辑div时切换div?还是有其他解决方案?我不允许使用JavaScript/jQuery
多谢各位
干杯,
JohnRamb0r我想说的是,您几乎是在与JSF及其在代码示例中的工作方式对抗。在向您展示一个工作示例之前,我想说几件与良好实践相关的事情:
- 不要直接调用方法,请使用属性引用的内置翻译。对
的引用将自动转换为对data.locked
的调用。最好调用data.isLocked()
,因为这会导致框架对其进行计算,而不是发送已计算的值data.locked
- 使用JSF-不要反对它。在您的示例代码中有许多不必要的ID以及使用不必要的标记和索引。保持简单并使用框架。直接引用对象而不是引用id,它简化了代码并使其更易于在页面上使用
- 将操作作为业务逻辑和结果的主要执行者。动作侦听器是预先执行的,可用于拦截或停止主动作的执行。因此,它们适合在执行业务逻辑之前用作验证步骤
- 标记您的事件。在命名接收用户事件的方法时,最好使用上的命名约定。这使您能够清楚地识别它们
div/outputPanel
是如何包装在另一个容器(表单)中的。如果我们跳过包装,而是直接在包装好的容器上推送更新,那么在刷新期间容器的呈现的
标记将永远不会更新,因此div将永远不会显示。在这种特殊情况下,这就是为什么表单是在容器外部而不是内部定义的
本例使用了一个@ViewScoped
bean,因此只要您停留在页面上,备份数据就应该保持不变。如果重新加载页面,您将获得一个包含新实体的新数据集,因为这将重新初始化支持bean并再次调用@PostConstruct
另请参见
- 不要直接调用方法,请使用属性引用的内置翻译。对
的引用将自动转换为对data.locked
的调用。最好调用data.isLocked()
,因为这会导致框架对其进行计算,而不是发送已计算的值data.locked
- 使用JSF-不要反对它。在您的示例代码中有许多不必要的ID以及使用不必要的标记和索引。保持简单并使用框架。直接引用对象而不是引用id,它简化了代码并使其更易于在页面上使用
- 将操作作为业务逻辑和结果的主要执行者。动作侦听器是预先执行的,可用于拦截或停止主动作的执行。因此,它们适合在执行业务逻辑之前用作验证步骤
- 标记您的事件。在命名接收用户事件的方法时,最好使用上的命名约定。这使您能够清楚地识别它们
div/outputPanel
是如何包装在另一个容器(表单)中的。如果我们跳过包装,而是直接在包装好的容器上推送更新,那么在刷新期间容器的呈现的
标记将永远不会更新,因此div将永远不会显示。在这种特殊情况下,这就是为什么表单是在容器外部而不是内部定义的
本例使用了一个@ViewScoped
bean,因此只要您停留在页面上,备份数据就应该保持不变。如果重新加载页面,您将获得一个包含新实体的新数据集,因为这将重新初始化支持bean并再次调用@PostConstruct
另请参见
edit{data.id}
。也许这就是问题所在。你收到错误信息了吗?如果您只需要update=
的id,您应该输入Hi,thx作为您的答案。span只是一个例子,说明这个“解决方案”有效,而panelGrid部分无效。我需要rendered选项来更新panelGrid,因此我想使用它。一个问题是,在具有rendered属性的组件中放置(更新)id。如果未呈现此组件,则无法使用id。正如我所写的:您应该将panelGrid放置在
中,其他组件不必获得相同的id。现在,我删除了span标记,并将panelGrid包装在panelGroup中。输出是
@Data
@Named
@ViewScoped
public class DataListViewBackingBean implements Serializable {
private Entity entity;
private Entity selectedEntity;
private List<Entity> dataEntities;
@PostConstruct
private void init() {
dataEntities = new ArrayList<>();
for (int i = 0; i < 10; i++) {
dataEntities.add(new Entity(i, RandomUtils.nextBoolean(),
RandomStringUtils.randomAlphabetic(30)));
}
}
@Data
@AllArgsConstructor
@EqualsAndHashCode(exclude = {"locked","description"})
public class Entity {
private int id;
private boolean locked;
private String description;
}
public void onEdit(Entity entity) {
selectedEntity = entity;
}
public void onDelete(Entity entity) {
dataEntities.remove(entity);
selectedEntity = null;
}
}
<?xml version="1.0" encoding="UTF-8"?>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html" xmlns:p="http://primefaces.org/ui">
<h:head>
<title>Data list test</title>
</h:head>
<h:body>
<h:form id="items">
<p:dataList type="definition" value="#{dataListViewBackingBean.dataEntities}" var="entity">
<div class="ui-g">
<div class="ui-g-8">
#{entity.description}
</div>
<div class="ui-g-4" style="text-align: right">
<p:commandButton value="Edit" disabled="#{entity.locked}" action="#{dataListViewBackingBean.onEdit(entity)}" update=":edit" />
<p:commandButton value="Delete" disabled="#{entity.locked}" action="#{dataListViewBackingBean.onDelete(entity)}" update="@form :edit" />
</div>
</div>
</p:dataList>
</h:form>
<h:form id="edit">
<p:outputPanel rendered="#{dataListViewBackingBean.selectedEntity != null}">
<h1>Editing...</h1>
<p:inputText placeholder="Description" value="#{dataListViewBackingBean.selectedEntity.description}" />
<p:commandButton value="Save" update=":items" />
</p:outputPanel>
</h:form>
</h:body>
</html>