【发布时间】:2019-03-23 10:27:07
【问题描述】:
我正在使用 JSF 构建一个简单的电子商店。有一个包含所有产品列表的页面 (product-list.xhtml),然后是每个产品的详细信息页面 (product.xhtml)。产品列表.xhtml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
xmlns:f="http://xmlns.jcp.org/jsf/core">
<h:head>
</h:head>
<h:body>
<f:view>
<h:outputText value="Number of items in the cart: #{shoppingCart.numberOfSelectedProducts}"/>
<h:link value="Cart" outcome="cart.xhtml"/>
<h:dataTable value="#{productController.products}" var="p">
<h:column>
#{p.name}
<h:commandLink action="product.xhtml" value="Detail">
<f:actionListener target="#{product.id}" value="#{p.id}"/>
</h:commandLink>
</h:column>
<h:column>
</h:column>
</h:dataTable>
</f:view>
</h:body>
</html>
product.xhtml 如下所示:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
xmlns:f="http://xmlns.jcp.org/jsf/core">
<head></head>
<!--f:metadata>
<f:event type="preRenderView" listener="#{shoppingCart.loadSelectedProduct(param.id)}"/>
</f:metadata -->
<body>
<f:view>
<h:graphicImage value="resources/images/img.jpg"/>
<h:outputLabel value="The value of shoppingCart.selectedProduct is: #{shoppingCart.selectedProduct.id}"/>
</f:view>
</body>
</html>
当我在调试器中运行应用程序时,该值已正确设置为 selectedProduct 属性,但随后无法在页面中访问 - product.xhtml 的输出如下所示(如果所选产品的 ID 为 4):
The value of shoppingCart.selectedProduct is:
主页上的产品是从 RequestScoped bean 的 (productController) 属性加载的。 ShoppingCart 是一个带有注入 productController 实例的 SessionScoped bean。
package main.java;
import javax.annotation.PostConstruct;
import javax.enterprise.context.SessionScoped;
import javax.inject.Named;
import java.io.Serializable;
import java.util.List;
@Named
@SessionScoped
public class ShoppingCart implements Serializable {
private List<Product> selectedProducts;
private int numberOfSelectedProducts;
private Product selectedProduct;
public Product getSelectedProduct() {
return selectedProduct;
}
public void setSelectedProduct(Product selectedProduct) {
this.selectedProduct = selectedProduct;
}
public List<Product> getSelectedProducts() {
return selectedProducts;
}
public void setSelectedProducts(List<Product> selectedProducts) {
this.selectedProducts = selectedProducts;
}
public int getNumberOfSelectedProducts() {
return numberOfSelectedProducts;
}
public void setNumberOfSelectedProducts(int numberOfSelectedProducts) {
this.numberOfSelectedProducts = numberOfSelectedProducts;
}
}
import javax.annotation.PostConstruct;
import javax.faces.view.ViewScoped;
import javax.inject.Inject;
import javax.inject.Named;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
@ViewScoped
@Named
public class ProductController implements Serializable {
private List<Product> products;
@Inject
private ShoppingCart shoppingCart;
public void setProducts(List<Product> products) {
this.products = products;
}
public ShoppingCart getShoppingCart() {
return shoppingCart;
}
public void setShoppingCart(ShoppingCart shoppingCart) {
this.shoppingCart = shoppingCart;
}
public List<Product> getProducts() {
return products;
}
//v teto metode se pote budou nacitat produkty z DB
@PostConstruct
public void loadItems(){
products = new ArrayList<>();
products.add(new Product(1, "Nazev1", 11, "Popis1"));
products.add(new Product(2, "Nazev2", 22, "Popis2"));
products.add(new Product(3, "Nazev3", 33, "Popis3"));
products.add(new Product(4, "Nazev4", 44, "Popis4"));
products.add(new Product(5, "Nazev5", 55, "Popis5"));
products.add(new Product(6, "Nazev6", 66, "Popis6"));
products.add(new Product(7, "Nazev7", 77, "Popis7"));
}
public Product findById(final int id) {
List<Product> product = products.stream().filter(p -> p.getId() == id).limit(1).collect(Collectors.toList());
return product.get(0);
}
}
package main.java;
import javax.annotation.PostConstruct;
import javax.faces.view.ViewScoped;
import javax.inject.Named;
import java.io.Serializable;
@Named
@ViewScoped
public class Product implements Serializable {
private int id;
private String name;
private double price;
private String description;
public Product(int id, String name, double price, String description) {
this.id = id;
this.name = name;
this.price = price;
this.description = description;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
@PostConstruct
public void init(){
System.out.println("Product created");
}
}
【问题讨论】:
-
请编辑您的问题以提供minimal reproducible example。
-
添加了更多信息。
-
关于您上次编辑@Spasitel,您可能建议使用
f:setPropertyActionListener。f:actionListener没有属性target或value