Java 仅当内部图像存在时才尝试有条件地显示div
基本上,我有一个复合,这是负责显示图像。但是这个图像被包装在一个Java 仅当内部图像存在时才尝试有条件地显示div,java,jsf,primefaces,jsf-2,Java,Jsf,Primefaces,Jsf 2,基本上,我有一个复合,这是负责显示图像。但是这个图像被包装在一个标签中,这个标签被包装在标签中。我试图实现的是,如果图像存在,只显示外部的 我的做法: 一开始我有这样的想法: <composite:implementation> <div class="logo-class"> <picture> <p:graphicImage value="#{bean.logo}" alt="{cc.attrs.nam
标签中,这个标签被包装在
标签中。我试图实现的是,如果图像存在,只显示外部的
我的做法:
一开始我有这样的想法:
<composite:implementation>
<div class="logo-class">
<picture>
<p:graphicImage value="#{bean.logo}" alt="{cc.attrs.name} - #{cc.attrs.location}">
<f:param name="key" value="#{cc.attrs.key}" />
</p:graphicImage>
</picture>
</div>
</composite:implementation>
我把合成图改成这样。不知道这种方法是否是最好的
<c:set var="logo" value="#{bean.getLogo(cc.attrs.key)}" />
<p:outputPanel rendered="#{logo != null}" styleClass="logo-class">
<picture>
<p:graphicImage value="#{logo}" alt="#{cc.attrs.name} - #{cc.attrs.location}" />
</picture>
</p:outputPanel>
标记结构是不可修改的
我的问题是,现在没有显示徽标图像,调试时我无法到达行Document Logo=logosService.read(key)代码>。如果(context.getCurrentPhaseId()==PhaseId.RENDER\u RESPONSE)
,我总是达到第一个条件。。。但是没有别的了。有什么问题吗?
提前谢谢
在bean
类中添加属性(boolean
),告诉您是否存在徽标
使用fragment
函数呈现
标记
示例强>
使用核心JSF标记库xmlns:ui=”http://java.sun.com/jsf/facelets“
将片段缠绕在
上
不会执行getLogo()
方法,因为布尔值检查将阻止它李>
您需要一个logoName、一个名为logo的延迟初始化派生字段和validLogo字段来标记logo中的值是否有效。当bean.logName发生更改时(需要再次加载),validLogo字段应重置为false
facelet:
<p:outputPanel rendered="#{myBean.logoExist}" styleClass="logo-class">
<picture>
<p:graphicImage value="#{myBean.logo}" alt="#{cc.attrs.name} - #{cc.attrs.location}" />
</picture>
</p:outputPanel>
在这种情况下,重新渲染的页面不希望从文件中重新加载徽标,直到徽标的名称没有更改(或者您没有离开视图)。如果(context.getCurrentPhaseId()==PhaseId.RENDER\u RESPONSE)返回null,则问题似乎是代码>。它的目的是什么?防止不必要的流,因为c:set?只是不要做c:set。一个组件的呈现
可以在一个请求中多次求值。最好别那么重。使用一种特殊的轻量级方法来检查图像是否存在。为什么不执行c:set
?在呈现
标记之前,我需要知道图像是否存在。。。因此,最好在支持bean上创建一个方法来检查图像是否存在?然后有这样一个条件:
,或者类似的东西,“为什么不做c:set?”忽略这部分。c:集合不会立即计算它的值,所以这无关紧要。无论如何,您奇怪的RENDER_响应检查和返回就是问题所在-p:outputPanel将永远不会因为它而被渲染。是的,一个专门的hasImage
检查会更优化性能。好的。那么hasImage()
方法将包含什么?我的意思是,我打电话给一个服务来阅读我的图片,我尝试了类似的方法。我将图像作为StreamedContent
直接存储在支持bean上,并在构造函数中设置StreamedContent
,xhtml如下所示:
。这个想法之所以有效,是因为没有显示没有图像的项目,并且显示了有图像的项目,但是只有alt
属性可见,而不是图像本身……您好。但如果有标识,将执行两次。基本上是为了知道是否有一个logo(用于布尔检查),需要调用一个返回内容的服务,mimetypeans等等。如果它存在,那么它将被p:graphicImage
再次调用,因此在最坏的情况下,如果我有一个包含200个项目的列表,每个项目都有一个徽标,那么该服务将被调用400次……好的,你的bean是什么范围?您将能够设置一个类型为Boolean(Object)的Bean变量,然后根据logo检查的第一次运行设置true/false,当它出现时,您可以获取图像内容。确保徽标检查尽可能轻,如果存在,则获取内容。
public StreamedContent getLogo(String key)
{
FacesContext context = FacesContext.getCurrentInstance();
if (context.getCurrentPhaseId() == PhaseId.RENDER_RESPONSE)
return null;
if (key == null || key.isEmpty())
return null;
try
{
Document logo= logosService.read(key);
if (logo== null)
return null;
return new ByteArrayContent(logo.getContent(), logo.getMimeType(), logo.getFilename());
}
catch (ValidationException ve)
{
return null;
}
}
<ui:fragment rendered="#{bean.logoPresent}">
<div class="logo-class">
<picture>
<p:graphicImage value="#{bean.logo}" alt="{cc.attrs.name} - #{cc.attrs.location}">
<f:param name="key" value="#{cc.attrs.key}" />
</p:graphicImage>
</picture>
</div>
</ui:fragment>
@Named
@ViewScoped
public class MyBean
{
// Attributes
private String logoName;
// Derived attributes
private boolean validLogo;
private Document logo;
public String getLogoName()
{
return logoName;
};
public void setLogoName( String logoName_ )
{
logoName = logoName_;
validLogo = false;
};
public boolean isLogoExist()
{
if ( !validLogo )
validateLogo();
return logo != null;
}
protected void validateLogo()
{
// The magic takes place here to load the image into the logo field
}
}
<p:outputPanel rendered="#{myBean.logoExist}" styleClass="logo-class">
<picture>
<p:graphicImage value="#{myBean.logo}" alt="#{cc.attrs.name} - #{cc.attrs.location}" />
</picture>
</p:outputPanel>