如何将数据从一个托管 Bean 传递到另一个托管 Bean?
How to pass data from one Managed Bean to another?
我正在使用 JSF 2.2 和 Primefaces 6.1 开发一个网站,最初我有 2 个页面:一个 "list" 页面,我可以在其中向用户显示数据,还有一个 "create"页面,我可以在其中创建新数据或编辑现有数据。
注:"Cargo"表示职业。
list.xhtml:
...
<h:form>
<p:commandButton value="Cadastrar" styleClass="ui-button-sucesso" action="create.xhtml?faces-redirect=true"/>
</h:form>
...
<h:form>
<p:dataTable value="#{cargoListMB.listaCargo}" var="cargo" rowKey="#{cargo.codigo}" emptyMessage="Nenhum cargo encontrado" filteredValue="#{cargoListMB.listaCargoFiltro}">
<f:facet name="header">Tabela de Cargos</f:facet>
<p:column headerText="Código" sortBy="#{cargo.codigo}" filterBy="#{cargo.codigo}" filterPosition="top">
<h:outputText value="#{cargo.codigo}"/>
</p:column>
<p:column headerText="Nome" sortBy="#{cargo.nome}" filterBy="#{cargo.nome}" filterPosition="top" filterMatchMode="contains">
<h:outputText value="#{cargo.nome}"/>
</p:column>
<p:column headerText="Funcionários" sortBy="#{cargo.funcionariosNesteCargo}"filterBy="#{cargo.funcionariosNesteCargo}" filterPosition="top">
<h:outputText value="#{cargo.funcionariosNesteCargo}"/>
</p:column>
<p:column headerText="Editar">
<p:commandButton icon="fa fa-pencil" title="Editar" styleClass="ui-button-icone-apenas" action="create.xhtml?faces-redirect=true">
<f:param name="objcargo" value="#{cargo.codigo}"/>
</p:commandButton>
</p:column>
</p:dataTable>
</h:form>
CargoListMB.java:
@ManagedBean(name = "cargoListMB")
@ViewScoped
public class CargoListMB implements Serializable {
private List<Cargo> listaCargo;
private List<Cargo> listaCargoFiltro;
public List<Cargo> getListaCargo() {
if (listaCargo == null) {
listaCargo = CargoDAO.listarTodos(); //load data from database
}
return listaCargo;
}
public void setListaCargo(List<Cargo> listaCargo) {
this.listaCargo = listaCargo;
}
...
}
create.xhtml:
<h:form>
<f:metadata>
<f:viewParam name="objcargo" value="#{cargoCreateMB.cargo}" converter="cargoConverter"/>
<f:viewAction action="#{cargoCreateMB.inicializar()}"/>
</f:metadata>
<div class="ui-grid ui-grid-responsive">
<div class="ui-grid-row">
<div class="ui-grid-col-6">
<h1 class="if-page-title"><h:outputText value="#{cargoCreateMB.cargo.codigo == 0? 'Cadastro de Cargos' : 'Edição de cargo'}"/></h1>
</div>
<div class="ui-grid-col-6"></div>
</div>
<br/>
<div class="ui-grid-row">
<div class="ui-grid-col-12">
<div class="ui-grid-row">
<div class="ui-grid-col-1">
<p:outputLabel for="nome" value="Nome:"/>
</div>
<div class="ui-grid-col-3">
<p:inputText id="nome" placeholder="nome" value="#{cargoCreateMB.cargo.nome}" required="true""/>
</div>
<div class="ui-grid-col-8">
<p:message for="nome"/>
</div>
</div>
<br/>
<div class="ui-grid-row">
<div class="ui-grid-col-3">
<p:commandButton value="Salvar" actionListener="#{cargoCreateMB.salvar}" update="form" styleClass="ui-button-salvar"/>
</div>
<div class="ui-grid-col-9"></div>
</div>
</div>
</div>
</div>
</h:form>
CargoCreateMB.java
@ManagedBean(name = "cargoCreateMB")
@ViewScoped
public class CargoCreateMB implements Serializable {
private Cargo cargo;
public void salvar() {
try {
ControleCargo.insereCargo(cargo); //saves the 'occupation' on the database
MensagensUtil.mensagemInfo("Atenção", "Cargo inserido com sucesso");
} catch (RuntimeException e) {
MensagensUtil.mensagemInfo("Erro", "Erro ao inserir cargo");
System.out.println("Erro: " + e);
}
}
public void inicializar() {
//QUESTION!! : Due to a JSF page's life cycle, could I put this code on the constructor??
if (this.cargo == null) {
this.limpar();
}
}
private void limpar() {
cargo = new Cargo();
}
public Cargo getCargo() {
return cargo;
}
public void setCargo(Cargo cargo) {
this.cargo = cargo;
}
}
如您所见,我正在尝试使用 <f:param>
和 <f:viewParam>
标记将选定的 'occupation' 从页面 list.xhtml 传递到 crate.xhtml。当我单击按钮 'Cadastrar'(表示 'register')时,一切正常("cargo" 对象最初为 null,正如预期的那样),但是当我单击编辑按钮时,"cargo.codigo"(职业的 ID)值,由 <f:param>
标签发送,不会 "arrive" 到 "cargo" 对象。转换器 ('cargoConverter') 应该工作正常,但是,当我检查方法 getAsObject 接收的字符串值时,无论我在列表中选择哪个职业,它总是“0”。
我还尝试发送 "raw" 数据:我没有使用转换器,而是将 "cargo.codigo" 值直接发送到字符串字段,但它始终为空。
有人可以帮助我发现我的错误是什么吗?另外,如果可能的话,是否有另一种方法可以将数据发送到其他托管 Bean?提前致谢。
编辑: 根据 Kukeltje 的评论,我格式化了我的代码(如上所示)并删除了所有嵌套的 <h:form>
元素,但问题仍然存在。因此,问题 How to use <h:form>
in JSF page? 的答案根本没有帮助,这个问题不是重复的。
根据 Kukeltje 的评论和提示以及对 this 问题的回答,我设法找到了我的错误:我的 <f:metadata>
确实在 <h:form>
中
标签。我从那里删除了它,它工作得很好。
我正在使用 JSF 2.2 和 Primefaces 6.1 开发一个网站,最初我有 2 个页面:一个 "list" 页面,我可以在其中向用户显示数据,还有一个 "create"页面,我可以在其中创建新数据或编辑现有数据。
注:"Cargo"表示职业。
list.xhtml:
...
<h:form>
<p:commandButton value="Cadastrar" styleClass="ui-button-sucesso" action="create.xhtml?faces-redirect=true"/>
</h:form>
...
<h:form>
<p:dataTable value="#{cargoListMB.listaCargo}" var="cargo" rowKey="#{cargo.codigo}" emptyMessage="Nenhum cargo encontrado" filteredValue="#{cargoListMB.listaCargoFiltro}">
<f:facet name="header">Tabela de Cargos</f:facet>
<p:column headerText="Código" sortBy="#{cargo.codigo}" filterBy="#{cargo.codigo}" filterPosition="top">
<h:outputText value="#{cargo.codigo}"/>
</p:column>
<p:column headerText="Nome" sortBy="#{cargo.nome}" filterBy="#{cargo.nome}" filterPosition="top" filterMatchMode="contains">
<h:outputText value="#{cargo.nome}"/>
</p:column>
<p:column headerText="Funcionários" sortBy="#{cargo.funcionariosNesteCargo}"filterBy="#{cargo.funcionariosNesteCargo}" filterPosition="top">
<h:outputText value="#{cargo.funcionariosNesteCargo}"/>
</p:column>
<p:column headerText="Editar">
<p:commandButton icon="fa fa-pencil" title="Editar" styleClass="ui-button-icone-apenas" action="create.xhtml?faces-redirect=true">
<f:param name="objcargo" value="#{cargo.codigo}"/>
</p:commandButton>
</p:column>
</p:dataTable>
</h:form>
CargoListMB.java:
@ManagedBean(name = "cargoListMB")
@ViewScoped
public class CargoListMB implements Serializable {
private List<Cargo> listaCargo;
private List<Cargo> listaCargoFiltro;
public List<Cargo> getListaCargo() {
if (listaCargo == null) {
listaCargo = CargoDAO.listarTodos(); //load data from database
}
return listaCargo;
}
public void setListaCargo(List<Cargo> listaCargo) {
this.listaCargo = listaCargo;
}
...
}
create.xhtml:
<h:form>
<f:metadata>
<f:viewParam name="objcargo" value="#{cargoCreateMB.cargo}" converter="cargoConverter"/>
<f:viewAction action="#{cargoCreateMB.inicializar()}"/>
</f:metadata>
<div class="ui-grid ui-grid-responsive">
<div class="ui-grid-row">
<div class="ui-grid-col-6">
<h1 class="if-page-title"><h:outputText value="#{cargoCreateMB.cargo.codigo == 0? 'Cadastro de Cargos' : 'Edição de cargo'}"/></h1>
</div>
<div class="ui-grid-col-6"></div>
</div>
<br/>
<div class="ui-grid-row">
<div class="ui-grid-col-12">
<div class="ui-grid-row">
<div class="ui-grid-col-1">
<p:outputLabel for="nome" value="Nome:"/>
</div>
<div class="ui-grid-col-3">
<p:inputText id="nome" placeholder="nome" value="#{cargoCreateMB.cargo.nome}" required="true""/>
</div>
<div class="ui-grid-col-8">
<p:message for="nome"/>
</div>
</div>
<br/>
<div class="ui-grid-row">
<div class="ui-grid-col-3">
<p:commandButton value="Salvar" actionListener="#{cargoCreateMB.salvar}" update="form" styleClass="ui-button-salvar"/>
</div>
<div class="ui-grid-col-9"></div>
</div>
</div>
</div>
</div>
</h:form>
CargoCreateMB.java
@ManagedBean(name = "cargoCreateMB")
@ViewScoped
public class CargoCreateMB implements Serializable {
private Cargo cargo;
public void salvar() {
try {
ControleCargo.insereCargo(cargo); //saves the 'occupation' on the database
MensagensUtil.mensagemInfo("Atenção", "Cargo inserido com sucesso");
} catch (RuntimeException e) {
MensagensUtil.mensagemInfo("Erro", "Erro ao inserir cargo");
System.out.println("Erro: " + e);
}
}
public void inicializar() {
//QUESTION!! : Due to a JSF page's life cycle, could I put this code on the constructor??
if (this.cargo == null) {
this.limpar();
}
}
private void limpar() {
cargo = new Cargo();
}
public Cargo getCargo() {
return cargo;
}
public void setCargo(Cargo cargo) {
this.cargo = cargo;
}
}
如您所见,我正在尝试使用 <f:param>
和 <f:viewParam>
标记将选定的 'occupation' 从页面 list.xhtml 传递到 crate.xhtml。当我单击按钮 'Cadastrar'(表示 'register')时,一切正常("cargo" 对象最初为 null,正如预期的那样),但是当我单击编辑按钮时,"cargo.codigo"(职业的 ID)值,由 <f:param>
标签发送,不会 "arrive" 到 "cargo" 对象。转换器 ('cargoConverter') 应该工作正常,但是,当我检查方法 getAsObject 接收的字符串值时,无论我在列表中选择哪个职业,它总是“0”。
我还尝试发送 "raw" 数据:我没有使用转换器,而是将 "cargo.codigo" 值直接发送到字符串字段,但它始终为空。
有人可以帮助我发现我的错误是什么吗?另外,如果可能的话,是否有另一种方法可以将数据发送到其他托管 Bean?提前致谢。
编辑: 根据 Kukeltje 的评论,我格式化了我的代码(如上所示)并删除了所有嵌套的 <h:form>
元素,但问题仍然存在。因此,问题 How to use <h:form>
in JSF page? 的答案根本没有帮助,这个问题不是重复的。
根据 Kukeltje 的评论和提示以及对 this 问题的回答,我设法找到了我的错误:我的 <f:metadata>
确实在 <h:form>
中
标签。我从那里删除了它,它工作得很好。