diff --git a/TODO b/TODO index 5ad25df87..855988852 100644 --- a/TODO +++ b/TODO @@ -36,6 +36,9 @@ ghttp.Request增加对输入参数的自动HtmlEncode机制; 服务注册时判断方法定义满足规范时才执行绑定,否则提示WARN信息; Cookie设置中文失效问题; ghttp hook回调使用方式在注册路由比较多的时候,优先级可能使得开发者混乱,考虑方式便于管理; +使用gconv将slice映射到struct属性上,例如redis hscan的结果集; + + DONE: 1. gconv完善针对不同类型的判断,例如:尽量减少sprintf("%v", xxx)来执行string类型的转换; diff --git a/g/frame/gins/gins.go b/g/frame/gins/gins.go index 24911b19b..6a963356b 100644 --- a/g/frame/gins/gins.go +++ b/g/frame/gins/gins.go @@ -64,8 +64,13 @@ func SetIfNotExist(key string, value interface{}) bool { } // 核心对象:View -func View() *gview.View { - return instances.GetOrSetFuncLock(gFRAME_CORE_COMPONENT_NAME_VIEW, func() interface{} { +func View(name...string) *gview.View { + group := "default" + if len(name) > 0 { + group = name[0] + } + key := fmt.Sprintf("%s.%s", gFRAME_CORE_COMPONENT_NAME_VIEW, group) + return instances.GetOrSetFuncLock(key, func() interface{} { path := gcmd.Option.Get("gf.viewpath") if path == "" { path = genv.Get("gf.viewpath") diff --git a/g/g_object.go b/g/g_object.go index bd2d9bd67..ff298fdb4 100644 --- a/g/g_object.go +++ b/g/g_object.go @@ -33,8 +33,8 @@ func UdpServer(name...interface{}) *gudp.Server { } // 核心对象:View -func View() *gview.View { - return gins.View() +func View(name...string) *gview.View { + return gins.View(name...) } // Config配置管理对象 diff --git a/g/os/gview/gview.go b/g/os/gview/gview.go index 5e14952eb..962026dab 100644 --- a/g/os/gview/gview.go +++ b/g/os/gview/gview.go @@ -24,6 +24,7 @@ import ( type View struct { mu sync.RWMutex paths *gspath.SPath // 模板查找目录(绝对路径) + data map[string]interface{} // 模板变量 funcmap map[string]interface{} // FuncMap delimiters []string // 模板变量分隔符号 } @@ -72,6 +73,7 @@ func New(path string) *View { s.Set(path) view := &View { paths : s, + data : make(map[string]interface{}), funcmap : make(map[string]interface{}), delimiters : make([]string, 2), } @@ -93,6 +95,22 @@ func (view *View) AddPath(path string) error { return view.paths.Add(path) } +// 批量绑定模板变量,即调用之后每个线程都会生效,因此有并发安全控制 +func (view *View) Assigns(data Params) { + view.mu.Lock() + for k, v := range data { + view.data[k] = v + } + view.mu.Unlock() +} + +// 绑定模板变量,即调用之后每个线程都会生效,因此有并发安全控制 +func (view *View) Assign(key string, value interface{}) { + view.mu.Lock() + view.data[key] = value + view.mu.Unlock() +} + // 解析模板,返回解析后的内容 func (view *View) Parse(file string, params map[string]interface{}, funcmap...map[string]interface{}) ([]byte, error) { path := view.paths.Search(file) @@ -111,7 +129,25 @@ func (view *View) Parse(file string, params map[string]interface{}, funcmap...ma if tpl, err := tplobj.Parse(content); err != nil { return nil, err } else { - if err := tpl.Execute(buffer, params); err != nil { + // 注意模板变量赋值不能改变已有的params或者view.data的值,因为这两个变量都是指针 + // 因此在必要条件下,需要合并两个map的值到一个新的map + vars := (map[string]interface{})(nil) + if len(view.data) > 0 { + if len(params) > 0 { + vars = make(map[string]interface{}, len(view.data) + len(params)) + for k, v := range params { + vars[k] = v + } + for k, v := range view.data { + vars[k] = v + } + } else { + vars = view.data + } + } else { + vars = params + } + if err := tpl.Execute(buffer, vars); err != nil { return nil, err } } @@ -131,7 +167,25 @@ func (view *View) ParseContent(content string, params map[string]interface{}, fu if tpl, err := tplobj.Parse(content); err != nil { return nil, err } else { - if err := tpl.Execute(buffer, params); err != nil { + // 注意模板变量赋值不能改变已有的params或者view.data的值,因为这两个变量都是指针 + // 因此在必要条件下,需要合并两个map的值到一个新的map + vars := (map[string]interface{})(nil) + if len(view.data) > 0 { + if len(params) > 0 { + vars = make(map[string]interface{}, len(view.data) + len(params)) + for k, v := range params { + vars[k] = v + } + for k, v := range view.data { + vars[k] = v + } + } else { + vars = view.data + } + } else { + vars = params + } + if err := tpl.Execute(buffer, vars); err != nil { return nil, err } } diff --git a/geg/os/gview/assign/assign.go b/geg/os/gview/assign/assign.go new file mode 100644 index 000000000..f83fef161 --- /dev/null +++ b/geg/os/gview/assign/assign.go @@ -0,0 +1,18 @@ +package main + + +import ( + "fmt" + "gitee.com/johng/gf/g" + "gitee.com/johng/gf/g/os/gview" +) + +func main() { + g.View().Assigns(gview.Params{ + "k1" : "v1", + "k2" : "v2", + }) + b, err := g.View().ParseContent(`{{.k1}} - {{.k2}}`, nil) + fmt.Println(err) + fmt.Println(string(b)) +} \ No newline at end of file diff --git a/geg/other/test.go b/geg/other/test.go index fd6f3425b..42c384027 100644 --- a/geg/other/test.go +++ b/geg/other/test.go @@ -2,12 +2,9 @@ package main import ( "fmt" - "gitee.com/johng/gf/g/util/grand" ) func main() { - for i := 0; i < 10; i++ { - //fmt.Println(grand.RandStr(3)) - fmt.Println(grand.Rand(100, 200)) - } + fmt.Println(string([]byte{48})) + fmt.Println(string([]byte{112,108,97,121,101,114,105,100})) }