Revel模板不支持局部刷新,需前端fetch调用独立Action返回HTML片段,并显式注册模板函数、设置响应头及清理缓存。

Revel 模板本身不支持局部刷新,得靠前端配合
Revel 是服务端渲染框架,所有模板渲染都在 HTTP 响应阶段完成,ExecuteTemplate 一调用,整个 HTML 就吐出去了。它没有内置的「局部刷新」机制,所谓「局部刷新」实际是前端发新请求、后端返回片段 HTML 或 JSON,再由 JS 替换 DOM。常见做法是:后端提供一个只渲染 user_card.html 这类 fragment 的独立 Action,前端用 fetch 拉取,然后 innerHTML = response.text()。
如何让 fragment 模板能独立渲染且复用主模板函数
直接复用主模板的 {{formatDate .CreatedAt}} 这类自定义函数会失败,因为 fragment 模板是单独解析的,没继承主模板的 Funcs。必须显式注入:
- 在
app/init.go的init()函数里注册函数:revel.TemplateFuncs["formatDate"] = func(t time.Time) string { return t.Format("2006-01-02") } - 确保该函数在
revel.Run()之前注册(即 init 阶段),否则运行时找不到 - fragment 模板文件(如
views/partials/user_card.html)不能依赖未注册的函数,否则报错位置难定位——建议先在主模板里验证函数可用
返回 fragment 时要注意 Content-Type 和缓存头
如果前端用 fetch 拉 fragment,后端返回的响应头若仍是 text/html 但没设 Vary: Accept 或禁用缓存,CDN 或浏览器可能把 fragment 当整页缓存,导致后续请求拿到旧内容。
- 在 fragment Action 里手动设置:
c.Response.Out.Header().Set("Content-Type", "text/html; charset=utf-8") - 开发期加:
c.Response.Out.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate") - 生产环境建议用 ETag 或基于数据版本的
Last-Modified,避免全量禁用缓存影响性能
容易被忽略的调试陷阱:dev 模式下 fragment 报错不显示行号
Revel 的错误映射(views/partials/user_card.html:23)默认只对主模板生效。fragment 模板出错时,堆栈常指向 template.go:xxx,根本看不出哪行 HTML 写错了。
- 必须在
conf/app.conf中确认mode = dev且results = true -
每次改完 fragment 模板,都要执行
revel clean清空app/tmp/,否则旧编译缓存会屏蔽新行号映射 - 临时加
{{print .User}}到 fragment 开头,可快速验证数据是否传入、字段名是否拼错——Revel 对字段访问失败静默返回空,不报错


















