迭代器上的 FreeMarker ?has_content

FreeMarker ?has_content on Iterator

FreeMarker 如何为 Iterator 实现 .iterator()?has_content? 它是否尝试获取第一个项目来决定是否渲染, 它是否保留它进行迭代?还是会开始另一次迭代?

我找到了这个

static boolean isEmpty(TemplateModel model) throws TemplateModelException
{
    if (model instanceof BeanModel) {
        ...
    } else if (model instanceof TemplateCollectionModel) {
        return !((TemplateCollectionModel) model).iterator().hasNext();
        ...
    }
}

但我不确定 Freemarker 将 Iterator 类型包装成什么。 是TemplateCollectionModel吗?

它没有获取第一项,它只是调用 hasNext(),是的,默认 ObjectWrapper(请参阅 object_wrapper 配置设置)它将被视为a TemplateCollectionModel,但只能列出一次。但是在 2.3.24 之前(我写这篇文章时它还没有发布),有一些小问题需要注意(见下文)。此外,如果您使用纯 BeansWrapper 而不是默认的 ObjectWrapper,则会出现故障(也请参见下文)。

Glitch (2.3.23 and earlier): 如果你使用的是默认的ObjectWrapper(你应该),而Iterator没有为后续的listing重新get,即相同的已经包装的值被重用,然后它会惊慌失措地说 Iterator 只能列出一次。

故障 2,纯 BeansWrapper:它总是会说它有内容,即使 Iterator 是空的。这也在 2.3.24 中修复,但是,您需要使用 2.3.24 incompatibleImprovements 创建 BeansWrapper 本身(即,不(只是)Configuration)才能激活修复.

请注意,<#list ...>...<#else>...</#list> 在所有情况下一直有效(甚至在 2.3.24 之前)。

最后,感谢您让我注意到这个话题。因此,我在 2.3.24 中修复了这些问题。 (可以从这里构建 Nightly:https://github.com/apache/incubator-freemarker/tree/2.3-gae