使用 ui:repeat 和 b:carousel?

Posted

技术标签:

【中文标题】使用 ui:repeat 和 b:carousel?【英文标题】:Use ui:repeat with b:carousel? 【发布时间】:2016-12-31 12:52:25 【问题描述】:

环境:

我正在使用 JSF2.2、Bootsfaces 0.9.1、Primefaces 6.0、JEE7 和 Hibernate 5.2 以及 mysql 5.7 DB。

我有什么:

我有一个模型,其中包含一组图像。该集合包含我的自定义 Image 类的实例,该类包含 Image 的值,例如标题、描述和文件名。

图像存储在文件系统中,我获得了用于存储模型的 MySQL DB。我试图在我的 web 应用程序的视图上显示图像,一切正常。我还展示了一些来自 bootsfaces 的带有 b:carousel 标签的图像,一切都像我预期的那样工作。

我想做什么:

我尝试的下一步是用于显示一组不同大小的图像。以下代码是我尝试实现的:

<b:carousel id="carousel" style="width: 800px; height: 400px;">
    <ui:repeat value="#modelDetailBean.modelImages" var="img">
         <b:carouselItem>
              <b:image value="#modelDetailBean.getImage(img)"/>
         </b:carouselItem>
    </ui:repeat>
</b:carousel>

我发现我的轮播中没有显示任何图像。然后我添加了至少 1 个固定值以查看它是否正常工作,并识别出该集合的所有图像都存在于轮播中,但是轮播没有正确考虑它们。

我的主要问题:

是否可以使用 ui:repeat 标签填充轮播?

如果可能的话:我该怎么做?我在这里做错了什么?

如果不是:我必须使用 JSF 实现哪些替代方案,而无需大量的 javascript 等等?

【问题讨论】:

【参考方案1】:

基本上,b:carousel 组件需要静态项,但ui:repeat 会动态呈现它们。解决方案是将b:carouselItems 的生成转移到早期的JSF 生命周期阶段。

JSF 分阶段执行其生命周期,负责呈现响应的生命周期是最后一个(在下面的链接中有很好的解释)。这里的关键点是您仍然可以使用 JSTL,它是一个标签处理程序而不是一个组件,并且在视图构建时执行。所以,基本上,用c:forEach 替换你的ui:repeat 应该可以解决你的问题:

<b:carousel id="carousel" style="width: 800px; height: 400px;">
    <c:forEach items="#modelDetailBean.modelImages" var="img">
         <b:carouselItem>
              <b:image value="#modelDetailBean.getImage(img)"/>
         </b:carouselItem>
    </c:forEach>
</b:carousel>

这个技巧曾经让开发人员在较早的 Mojarra JSF 版本(2.1.18 和更早版本)中遇到 PARTIAL_STATE_SAVING 的麻烦,但现在不再这样了。无论如何,请始终牢记 JSTL 在评估组件之前执行。从下面的链接:

仅使用 JSTL 标签来控制 JSF 组件树构建的流程。采用 用于控制 html 输出生成流程的 JSF UI 组件。不要 将迭代 JSF 组件的 var 绑定到 JSTL 标签属性。做 不依赖 JSTL 标签属性中的 JSF 事件。

或者,忘记 b:carousel 组件,您可以将 JSF 用作单纯的 HTML 生成器,并使用普通 Bootstrap 生成显示轮播所需的 HTML,如 自己动手docs 的部分。

另请参阅:

JSTL in JSF2 Facelets... makes sense? What's the view build time?

【讨论】:

很好解释,成功了!不幸的是,我遇到了另一个问题。我会就此提出一个新问题。 更重要的是,在b:carousel 和它的b:courouselItems 之间放置一个ui:repeat 会修改项目的HTML id。我没有检查客户端小部件是否能处理修改后的 id,但许多小部件没有。更糟糕的是,JSF 树看起来与 BootsFaces 预期的不同。它看到ui:repeat。该组件被静默忽略。 b:carouselItemui:repeat 的子代 - 或 b:carousel 的孙代。我们还没有教 BootsFaces 关心孙辈。另外,ui:repeat 的子级在渲染阶段被渲染——对于 BootsFaces 来说是延迟。 @Xtreme Biker:也许您想改写答案的第一句话。你的其余答案是正确的。 b:carousel 需要静态内容,因此如果修改 JSF 树的解决方案 - 这就是 JSTL 标记所做的。 @StephanRauh 我认为这就是所说的,但您可以随意编辑我的答案! 你看到我的编辑了吗?目前,它正在等待同行评审。我希望你喜欢这个编辑。

以上是关于使用 ui:repeat 和 b:carousel?的主要内容,如果未能解决你的问题,请参考以下文章

使用 ui:repeat 输出 ResultSet

在包含的 facelet 中使用 ui:repeat 时,ui:include 的动态呈现将不起作用

有条件地渲染 tr,使用 ui:repeat 构建表

使用 JSF ui:repeat 循环执行带状态的逻辑

c:forEach vs ui:repeat(又名 ice:panelSeries)

是否可以使用ui:在ui中重复:include