AEM WKND开发调用data-sly-use后Byline组件隐藏问题咨询
Byline组件引入Sling Model后自动隐藏的修复方案
核心原因
组件被隐藏本质是HTL中data-sly-test.hasContent="${!byline.empty}"判定结果为false,要么是Sling Model适配失败返回null,要么是isEmpty()逻辑返回true,另外代码中存在几处语法和逻辑错误会直接触发该问题,逐一修复即可。
修复步骤
- 修正HTL根节点语法错误:当前
byline.html的根div标签漏写了开头的<,现有写法div data-sly-use.byline="xxx"不会被HTL引擎识别为标签,所有绑定的Sling Model、test逻辑都不会执行,直接把开头改成<div即可。 - 修正Sling Model引用路径:你的Sling Model注解配置了
adapters = {Byline.class},适配为接口暴露,HTL中不要直接引用实现类com.adobe.aem.guides.wknd.core.models.impl.BylineImpl,改成引用接口全限定名,例如com.adobe.aem.guides.wknd.core.models.Byline,否则会触发适配失败,Model返回null导致组件隐藏。 - 修正Image资源的引用路径:当前HTL中
data-sly-resource写的是${ '.' @ resourceType = 'core/wcm/components/image/v2/image' },会把Byline组件自身的资源传给Image组件解析,而Byline节点本身不存储Image组件需要的fileReference等图片属性,会导致Image的src为空,触发isEmpty()返回true。把这部分改成${ 'image' @ resourceType = 'core/wcm/components/image/v2/image' },指向组件下名为image的子节点存储图片数据即可。 - 修正Sling Model中Image的初始化逻辑:原来的
@PostConstruct方法直接拿当前组件资源适配Image模型,拿不到正确的图片数据,改成读取image子节点再适配,同时加空判断避免初始化抛异常(@PostConstruct抛异常会直接导致整个Model适配失败):
@PostConstruct private void init(){ Resource imageRes = request.getResource().getChild("image"); if (imageRes != null) { image = modelFactory.getModelFromWrappedRequest(request, imageRes, Image.class); } }
- 补充Sling Model的适配范围:在
@Model注解的adaptables中补充Resource.class,即adaptables = {SlingHttpServletRequest.class, Resource.class},避免部分渲染场景下Model适配失败。 - 检查部署状态:确保core bundle在AEM中处于Active状态,Byline接口已正确导出,没有包导出限制导致HTL加载不到Model类。
修复后参考代码
byline.html
<div data-sly-use.byline="com.adobe.aem.guides.wknd.core.models.Byline" data-sly-use.placeholderTemplate="core/wcm/components/commons/v1/templates.html" data-sly-test.hasContent="${!byline.empty}" class="cmp-byline"> <div class="cmp-byline__image" data-sly-resource="${ 'image' @ resourceType = 'core/wcm/components/image/v2/image' }"></div> <h2 class="cmp-byline__name">${byline.name}</h2> <p class="cmp-byline__occupations">${byline.occupations @ join=', '}</p> </div> <sly data-sly-call="${placeholderTemplate.placeholder @ isEmpty=!hasContent}"></sly>
BylineImpl.java 关键注解与init方法
@Model(adaptables = {SlingHttpServletRequest.class, Resource.class}, adapters = {Byline.class}, resourceType = {BylineImpl.RESOURCE_TYPE}, defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL) public class BylineImpl implements Byline { protected static final String RESOURCE_TYPE = "wknd/components/byline"; // 其余注入的字段、getName/getOccupations/isEmpty/getImage方法保持原有逻辑即可,注意提前导入StringUtils依赖 @PostConstruct private void init(){ Resource imageRes = request.getResource().getChild("image"); if (imageRes != null) { image = modelFactory.getModelFromWrappedRequest(request, imageRes, Image.class); } } }
修复完成后重新部署ui.apps和core代码包,给Byline组件填全名称、职业信息、上传图片后即可正常渲染,未填充内容时会正常显示组件占位符,不会直接隐藏。
内容的提问来源于stack exchange,提问作者newbie
相关产品推荐
相关产品推荐

