Java 如何使用thymeleaf递归地呈现菜单

Java 如何使用thymeleaf递归地呈现菜单,java,spring,templates,web,thymeleaf,Java,Spring,Templates,Web,Thymeleaf,我想使用ul/li列表呈现HTML菜单。我有这样的班级结构: public class MenuItem { private String name; private MenuItem parent; private List<MenuItem> children; public MenuItem(String name,List<MenuItem> children) { this.name = name;

我想使用ul/li列表呈现HTML菜单。我有这样的班级结构:

public class MenuItem {

    private String name;

    private MenuItem parent;

    private List<MenuItem> children;

    public MenuItem(String name,List<MenuItem> children) {
        this.name = name;
        this.children = children;
        for (MenuItem child : children) {
            child.parent = this;
        }
    }

    public MenuItem(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public MenuItem getParent() {
        return parent;
    }

    public List<MenuItem> getChildren() {
        return children;
    }
} 
公共类菜单项{
私有字符串名称;
私有菜单项父项;
私人名单儿童;
公共菜单项(字符串名称,列表子项){
this.name=名称;
这个。孩子=孩子;
for(菜单项子项:子项){
child.parent=这个;
}
}
公共菜单项(字符串名称){
this.name=名称;
}
公共字符串getName(){
返回名称;
}
公共菜单项getParent(){
返回父母;
}
公共列表getChildren(){
返回儿童;
}
} 
正如您所看到的,它是典型的树结构,其中一个根元素包含对其子元素的引用,而子元素则包含对其子元素的引用,以此类推

现在,我想呈现如下结构:

<ul>
    <li>Item 1
        <ul>
            <li>Item 1.1</li>
            <li>Item 1.2
                <ul>
                    <li>Item 1.2.1</li>
                    <li>Item 1.2.3</li>
                </ul>
            </li>
            <li>Item 1.3</li>
        </ul>
    </li>
    <li>Item 2</li>
</ul>
  • 项目1
    • 项目1.1
    • 项目1.2
      • 项目1.2.1
      • 项目1.2.3
    • 项目1.3
  • 项目2
如何使用thymeleaf实现这一点?如果我必须使用其他技术,比如瓷砖、布局或其他任何东西,我会很容易

编辑:我尝试了参数化包含/替换,但没有成功。传递的参数被转换为字符串,不能用于其他级别的递归。看

多谢各位

弗兰克

试试这个:

为单个菜单项创建一个片段,如
menuffragment.html

<html>
    <section layout:fragment="menu">
        <ul>
            <li th:each="menuItem : ${menuItemsList}" th:text="${menuItem.name}">
                <section layout:include="@{path/to/folder/menuFragment} :: menu" th:with="menuItemsList=${menuItem.children}"></section>
            </li>
        </ul> 
    </section>
</html>

在菜单文件中包含片段,如下所示:

<section layout:include="@{path/to/folder/menuFragment} :: menu" th:with="menuItemsList=${rootMenuItemAsList}"></section>

rootMenuItemAsList
是一个包含父菜单的列表

希望此帮助能帮助您

尝试以下操作:

为单个菜单项创建一个片段,如
menuffragment.html

<html>
    <section layout:fragment="menu">
        <ul>
            <li th:each="menuItem : ${menuItemsList}" th:text="${menuItem.name}">
                <section layout:include="@{path/to/folder/menuFragment} :: menu" th:with="menuItemsList=${menuItem.children}"></section>
            </li>
        </ul> 
    </section>
</html>

在菜单文件中包含片段,如下所示:

<section layout:include="@{path/to/folder/menuFragment} :: menu" th:with="menuItemsList=${rootMenuItemAsList}"></section>

rootMenuItemAsList
是一个包含父菜单的列表


希望您能从中得到帮助

我尝试了这一点,在我看来:

    <li th:each="menuItem : ${menuItemsList}" th:text="${menuItem.name}">
        <section layout:include="@{path/to/folder/menuFragment} :: menu" th:with="menuItemsList=${menuItem.children}"></section>
  • 将覆盖include(在li-tag内),因为th:text属性正好覆盖li块内的内容

    我得到这个是为了与以下方面合作:

        <li th:each="menuItem : ${menuItemsList}">
            <span  th:text="${menuItem.name}">prototype text...</span>
            <section layout:include="@{path/to/folder/menuFragment} :: menu" th:with="menuItemsList=${menuItem.children}"></section>
        </li>
    
  • 原型文本。。。

  • 希望这能有所帮助……

    我试过这个,在我看来:

        <li th:each="menuItem : ${menuItemsList}" th:text="${menuItem.name}">
            <section layout:include="@{path/to/folder/menuFragment} :: menu" th:with="menuItemsList=${menuItem.children}"></section>
    
  • 将覆盖include(在li-tag内),因为th:text属性正好覆盖li块内的内容

    我得到这个是为了与以下方面合作:

        <li th:each="menuItem : ${menuItemsList}">
            <span  th:text="${menuItem.name}">prototype text...</span>
            <section layout:include="@{path/to/folder/menuFragment} :: menu" th:with="menuItemsList=${menuItem.children}"></section>
        </li>
    
  • 原型文本。。。
  • 希望这有助于…

    在我的主要内容中,我包括:

    <section th:include="@{categoryFragment} :: category" th:with="maincategories=${categories}"></section>
    
    
    
    作为我使用的片段:

    <section th:fragment="category">
        <ul>
            <li th:each="cat : ${maincategories}">
                <span th:text="${cat.categoryName}">Main Cat</span>
                <section th:include="@{categoryFragment} :: category" th:with="maincategories=${cat.getChildren()}"></section>
            </li>
        </ul>
    </section>
    
    
    
    • 主猫
    这对我来说绝对有效。

    主要包括:

    <section th:include="@{categoryFragment} :: category" th:with="maincategories=${categories}"></section>
    
    
    
    作为我使用的片段:

    <section th:fragment="category">
        <ul>
            <li th:each="cat : ${maincategories}">
                <span th:text="${cat.categoryName}">Main Cat</span>
                <section th:include="@{categoryFragment} :: category" th:with="maincategories=${cat.getChildren()}"></section>
            </li>
        </ul>
    </section>
    
    
    
    • 主猫

    这对我来说非常好。

    这段代码不起作用,因为父li元素中的th:text覆盖了片段中包含的部分。您必须在li元素上使用th:inline=“text”,并在内部节上方添加实际文本,而不是使用th:text[${menuItem.name}]],此代码不起作用,因为父li元素中的th:text覆盖了片段中包含的节。您必须在li元素上使用th:inline=“text”,而不是使用th:text,并在内部部分上方添加实际文本,如[${menuItem.name}]]