在Go语言的HTML模板中,遍历任意嵌套结构体的切片。

4

我希望创建一个类似Reddit的网络论坛。每个讨论主题有对应的回复,而回复也可以拥有自己的回复,以此类推。

一个讨论版块会长这样:

var board map[string]*Post

而且还有一个帖子

type Post struct {
  Title string
  Body string
  ID string
  PostNum int
  Replies []*Post
}

我该如何使用模板来遍历嵌套的Replies切片(请注意,每个*Post都包含一个包含*PostsReplies等内容的Replies切片)?

目前我所拥有的:

<div id="posts">                                              
  {{ .Title  }}  
  {{ .Body  }}    

  <ul>                                                        
  {{ range $key, $value := .Replies }}                        
    <li class="post">                                         
      <div class="postHead">                                  
        <div class="postTitle"><b>{{ $value.ID }}</b></div>   
      </div>                                                  
      <div class="postBody">{{ $value.PostNum }}</div>        
    </li>          

  <ul>                                   
  {{ range $key, $value := $value.Replies }}                  
    <li class="post">                                         
      <div class="postHead">                                  
        <div class="postTitle"><b>{{ $value.ID }}</b></div>   
      </div>                                                  
      <div class="postBody">{{ $value.PostNum }}</div>        
    </li>                                                     
  {{ end }}                                                   
  </ul>                                                       

  {{ end }}                                                   
  </ul>                                                       
</div>                                                        

这只允许我遍历两级回复(并且如您所见,使用了重复的代码),我需要能够遍历任意数量的回复层级。

2个回答

7

若要递归遍历层次结构,请使用一个执行自身的命名模板。在下面的示例中,模板“replies”执行“replies”以显示子回复:

{{define "main"}}
<div id="post">                                              
  {{.Title}}  
  {{.Body}}
  {{template "replies" .Replies}}
</div>
{{end}}

{{define "replies"}}
   {{if .}}
      <ul>
      {{range . }}                                  
         <li class="post">                                         
           <div class="postHead">                                  
             <div class="postTitle"><b>{{.Title}}</b></div>   
           </div>
           <div class="postBody">{{.Body}}</div>
           {{template "replies" .Replies}}
         </li>
      {{end}}
      </ul>
   {{end}}
{{end}}

示例代码

(关于IT技术的内容)

4
您刚刚定义了一个递归数据类型。您可以通过定义递归模板来呈现它:
{{define "replies"}}
  <ul>
    {{ range $key, $value := . }}
      <li class="post">
        <div class="postHead">
          <div class="postTitle"><b>{{ $value.ID }}</b></div>
        </div>
        <div class="postBody">{{ $value.PostNum }}</div>
      </li>

      {{template "replies" .Replies}}
    {{end}}
  </ul>
{{end}}

<div id="posts">
  {{ .Title  }}
  {{ .Body  }}

  {{ template "replies" .Replies }}
</div>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接