英文:
Pulling model directly from Revel template engine
问题
在Go/Revel的模板中,可以像在erb文件中那样直接从视图中获取模型数据吗?例如:
<script>
  var vm = {
    rows: {{ .ModelName.Rows | jsonify }}
  };
  // 使用客户端JavaScript渲染vm.rows
</script>
<div>
  bla bla
</div>
在Go/Revel的模板中,使用双大括号{{ }}来包裹模型数据,并使用管道符号|来调用相应的函数或过滤器。在上面的示例中,我们使用了.ModelName.Rows来获取模型数据,并使用jsonify过滤器将其转换为JSON格式。然后,我们将结果赋值给JavaScript变量vm.rows,以便在客户端使用JavaScript进行渲染。
英文:
I come from Ruby/PHP background, usually I use pull the model from the View directly without controller, for example inside an erb file:
<script>
  var vm = {
    rows: <%= ModelName.rows.to_json %>
  };
  // render vm.rows using client-side javascript
</script>
<div> 
  bla bla
</div>
Is it possible to pull model just like what I did in erb, inside Go/Revel's template?
答案1
得分: 2
将代码直接嵌入模板的方法只适用于解释型语言,如Ruby和PHP。Go模板包支持一些简单的指令(如if、else、range等-详见这里),但这种语法远远不及完整的脚本语言-这可能也不是预期的。你可以从模板中调用诸如to_json方法之类的方法。然而(正如twotwotwo正确指出的那样),你甚至可能不需要额外的方法将数据转换为JSON-如果将其放置在<script>标签之间,Go会自动进行转换。要自定义转换,请实现Marshaler接口,提供一个MarshalJSON方法,如这里所述。
以下示例演示了直接输出结构体,在“script”上下文中使用方法:
package main
import (
	"html/template"
	"log"
	"os"
	"strings"
)
type Greeter struct {
	Repeat     int
	Salutation string
}
func (g Greeter) Perform() string {
	return strings.Repeat(g.Salutation+" ", g.Repeat)
}
func main() {
	sayHi := Greeter{Repeat: 3, Salutation: "Hi!"}
	tmpl, err := template.New("").Parse("{{.}}\n<script>{{.}}</script>\n{{.Perform}}")
	if err != nil {
		log.Fatalf("Parse: %v", err)
	}
	tmpl.Execute(os.Stdout, sayHi)
}
输出:
{3 Hi!}
<script>{"Repeat":3,"Salutation":"Hi!"}</script>
Hi! Hi! Hi!
Revel是基于Go模板包构建的,而不是实现自己的模板系统,因此上述内容也适用于Revel。
英文:
This method of embedding code directly into a template can only be done with interpreted languages such as Ruby and PHP. The Go template packages support some simple instructions (if, else, range etc. - see here for details) but this syntax doesn't come close to a full scripting language - that's probably not intended either. You can call methods such as your to_json method from templates. However (as twotwotwo rightfully pointed out) you may not even need an extra method to convert your data to JSON - if you place it between <script> tags, Go will do the conversion by itself. To customize the conversion, implement the Marshaler interface by providing a MarshalJSON method as described here.
The following example demonstrates outputting a struct directly, in a "script" context and using a method:
package main
import (
	"html/template"
	"log"
	"os"
	"strings"
)
type Greeter struct {
	Repeat     int
	Salutation string
}
func (g Greeter) Perform() string {
	return strings.Repeat(g.Salutation+" ", g.Repeat)
}
func main() {
	sayHi := Greeter{Repeat: 3, Salutation: "Hi!"}
	tmpl, err := template.New("").Parse("{{.}}\n<script>{{.}}</script>\n{{.Perform}}")
	if err != nil {
		log.Fatalf("Parse: %v", err)
	}
	tmpl.Execute(os.Stdout, sayHi)
}
http://play.golang.org/p/f3HShZfd6H
Output:
{3 Hi!}
<script>{"Repeat":3,"Salutation":"Hi!"}</script>
Hi! Hi! Hi!
Revel builds on the Go template packages rather than implementing its own template system, so the above applies to Revel as well.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论