如何从<p:contentFlow>获取选中图片?传参为null问题求助
Hey there! I see you're having trouble passing your ImageModel to the backing bean when clicking an image in <p:contentFlow>—the parameter keeps coming through as null. Let's break down why this happens and how to fix it.
Why the Null Parameter Happens
The <p:contentFlow> is a client-side heavy component that renders dynamic HTML via JavaScript. Unlike standard JSF iteration components (like <p:dataGrid>), the image variable from the iteration isn't tracked in JSF's view state when the command link is clicked. That means when your getImagePath() method is called, JSF can't map the clicked image back to the original ImageModel instance, hence the null value.
Solution 1: Pass a Unique Identifier via <f:param>
The most reliable fix is to pass a unique identifier for each ImageModel (like an ID or unique name) as a request parameter, then look up the corresponding model in your bean.
Step 1: Update the XHTML Code
Add an <f:param> inside your <p:commandLink> to send the unique identifier. I'll assume your ImageModel has an id property—if you don't have one, you can use name instead (just make sure it's unique):
<h:form> <p:contentFlow value="#{viewer.images}" var="image"> <p:commandLink styleClass="content" action="#{viewer.getImagePath()}"> <p:graphicImage value="resources/images/#{image.name}" styleClass="content" /> <!-- Pass the unique identifier as a request parameter --> <f:param name="imageIdentifier" value="#{image.id}" /> </p:commandLink> </p:contentFlow> </h:form>
Step 2: Modify the Backing Bean
Update your getImagePath() method to retrieve the parameter, then look up the matching ImageModel from your list:
import javax.faces.context.FacesContext; import java.util.Map; import java.util.List; public class ViewerBean { // Your existing list of ImageModel instances private List<ImageModel> images; public void getImagePath() { // Get the request parameters from the current context FacesContext context = FacesContext.getCurrentInstance(); Map<String, String> requestParams = context.getExternalContext().getRequestParameterMap(); String imageId = requestParams.get("imageIdentifier"); // Look up the ImageModel using the identifier ImageModel clickedImage = findImageById(imageId); if (clickedImage != null) { System.out.println("Image path: " + clickedImage.getPath()); } else { System.out.println("No matching image found for identifier: " + imageId); } } // Helper method to find ImageModel by ID private ImageModel findImageById(String imageId) { for (ImageModel img : images) { if (img.getId().equals(imageId)) { // Adjust this check based on your identifier type return img; } } return null; } // Getters and setters for 'images' public List<ImageModel> getImages() { return images; } public void setImages(List<ImageModel> images) { this.images = images; } }
Alternative: Use image.name as the Identifier
If you don't have an id property on ImageModel and name is unique, just swap the <f:param> value to #{image.name} and adjust the findImageById() method to search by name instead:
private ImageModel findImageByName(String imageName) { for (ImageModel img : images) { if (img.getName().equals(imageName)) { return img; } } return null; }
Why This Works
By passing a unique identifier via <f:param>, we're explicitly sending the information needed to locate the correct ImageModel in the bean. This bypasses the view state limitation of the client-side <p:contentFlow> component, ensuring we can reliably fetch the image path.
内容的提问来源于stack exchange,提问作者Amir Shiati

