从 bean 访问 PrimeFaces 命令按钮以添加动作侦听器
accessing PrimeFaces command button from bean to add action listener
我在 ID 为 "save" 的视图中有以下命令按钮:
<p:panel style="border:none;text-align:left;margin:0;">
<p:commandButton value="Save Document" id="save" icon="fa fa-save"
disabled="#{dIGRCController.digrc.qconce == '020'}">
<f:param name="validate" value="true" />
</p:commandButton>
<p:commandButton value="Clear" icon="fa fa-undo"></p:commandButton>
</p:panel>
我正在尝试动态分配不同的 actionListener。如果用户想要插入一些新记录,我希望它调用插入方法。如果用户想要更新现有记录,则应调用 update 方法。
现在我正在尝试这样做:
@PostConstruct
public void init() {
// setting the action listener of the Save Document button
UIViewRoot viewRoot = FacesContext.getCurrentInstance().getViewRoot();
// UIComponent button = viewRoot.findComponent("save");
CommandButton button = (CommandButton) viewRoot.findComponent("save");
FacesContext context = FacesContext.getCurrentInstance();
MethodExpression methodExpression = context
.getApplication()
.getExpressionFactory()
.createMethodExpression(context.getELContext(),
"#{dIGRCController.updateDocument}", null,
new Class[] { DIGRCController.class });
button.addActionListener(new MethodExpressionActionListener(
methodExpression));
}
我在该行收到一个空指针异常:
button.addActionListener(new MethodExpressionActionListener(
methodExpression));
我做错了什么?还有另一种方法可以完成我想做的事情吗?我正在使用 JSF 2.2、PrimeFaces 5.3 和 OmniFaces 1.11。
findComponent()
将客户端 ID 作为参数而不是组件 ID。客户端 ID 正是与相关组件关联的生成的 HTML id
属性的值。在命令按钮的情况下,通常父组件 ID <h:form>
是前置的,由默认为 :
.
的命名容器分隔符分隔
鉴于此,
<h:form id="form">
<p:commandButton id="save" ... />
</h:form>
客户端 ID 将是 form:save
。
CommandButton button = (CommandButton) viewRoot.findComponent("form:save");
另请参阅有关识别和使用客户端 ID 的相关问题:How to find out client ID of component for ajax update/render? Cannot find component with expression "foo" referenced from "bar"
与具体问题无关,在Java端操作组件树是一种不好的做法。您最好为此继续使用 XHTML+XML,这对于 declaring/defining 树结构而言是更多的自我记录。您可以使用 JSTL 标签动态构建视图(注意:这不同于使用 rendered
属性动态渲染视图!)。
例如
<p:commandButton ... action="#{bean.save}">
<c:if test="#{bean.existing}">
<f:actionListener binding="#{bean.needsUpdate()}" />
</c:if>
</p:commandButton>
另见 JSTL in JSF2 Facelets... makes sense?
更重要的是,您可以将 #{bean.existing}
作为方法参数传递。
<p:commandButton ... action="#{bean.save(bean.existing)}" />
如果 #{bean.existing}
引用与 #{bean.save}
相同的 bean,那么这两种方法都被承认有点奇怪。您可以在 #{bean.save}
本身内部检查它。
public void save() {
if (existing) {
// UPDATE
} else {
// INSERT
}
}
更进一步,这不是前端层的责任,而是服务层的责任。您将整个实体传递给服务层,服务层会根据 PK 检查它是否存在。
if (entity.getId() == null) {
// INSERT
} else {
// UPDATE
}
我在 ID 为 "save" 的视图中有以下命令按钮:
<p:panel style="border:none;text-align:left;margin:0;">
<p:commandButton value="Save Document" id="save" icon="fa fa-save"
disabled="#{dIGRCController.digrc.qconce == '020'}">
<f:param name="validate" value="true" />
</p:commandButton>
<p:commandButton value="Clear" icon="fa fa-undo"></p:commandButton>
</p:panel>
我正在尝试动态分配不同的 actionListener。如果用户想要插入一些新记录,我希望它调用插入方法。如果用户想要更新现有记录,则应调用 update 方法。
现在我正在尝试这样做:
@PostConstruct
public void init() {
// setting the action listener of the Save Document button
UIViewRoot viewRoot = FacesContext.getCurrentInstance().getViewRoot();
// UIComponent button = viewRoot.findComponent("save");
CommandButton button = (CommandButton) viewRoot.findComponent("save");
FacesContext context = FacesContext.getCurrentInstance();
MethodExpression methodExpression = context
.getApplication()
.getExpressionFactory()
.createMethodExpression(context.getELContext(),
"#{dIGRCController.updateDocument}", null,
new Class[] { DIGRCController.class });
button.addActionListener(new MethodExpressionActionListener(
methodExpression));
}
我在该行收到一个空指针异常:
button.addActionListener(new MethodExpressionActionListener(
methodExpression));
我做错了什么?还有另一种方法可以完成我想做的事情吗?我正在使用 JSF 2.2、PrimeFaces 5.3 和 OmniFaces 1.11。
findComponent()
将客户端 ID 作为参数而不是组件 ID。客户端 ID 正是与相关组件关联的生成的 HTML id
属性的值。在命令按钮的情况下,通常父组件 ID <h:form>
是前置的,由默认为 :
.
鉴于此,
<h:form id="form">
<p:commandButton id="save" ... />
</h:form>
客户端 ID 将是 form:save
。
CommandButton button = (CommandButton) viewRoot.findComponent("form:save");
另请参阅有关识别和使用客户端 ID 的相关问题:How to find out client ID of component for ajax update/render? Cannot find component with expression "foo" referenced from "bar"
与具体问题无关,在Java端操作组件树是一种不好的做法。您最好为此继续使用 XHTML+XML,这对于 declaring/defining 树结构而言是更多的自我记录。您可以使用 JSTL 标签动态构建视图(注意:这不同于使用 rendered
属性动态渲染视图!)。
例如
<p:commandButton ... action="#{bean.save}">
<c:if test="#{bean.existing}">
<f:actionListener binding="#{bean.needsUpdate()}" />
</c:if>
</p:commandButton>
另见 JSTL in JSF2 Facelets... makes sense?
更重要的是,您可以将 #{bean.existing}
作为方法参数传递。
<p:commandButton ... action="#{bean.save(bean.existing)}" />
如果 #{bean.existing}
引用与 #{bean.save}
相同的 bean,那么这两种方法都被承认有点奇怪。您可以在 #{bean.save}
本身内部检查它。
public void save() {
if (existing) {
// UPDATE
} else {
// INSERT
}
}
更进一步,这不是前端层的责任,而是服务层的责任。您将整个实体传递给服务层,服务层会根据 PK 检查它是否存在。
if (entity.getId() == null) {
// INSERT
} else {
// UPDATE
}