github.com/zhongdalu/gf@v1.0.0/g/frame/gmvc/view.go (about)

     1  // Copyright 2017 gf Author(https://github.com/zhongdalu/gf). All Rights Reserved.
     2  //
     3  // This Source Code Form is subject to the terms of the MIT License.
     4  // If a copy of the MIT was not distributed with this file,
     5  // You can obtain one at https://github.com/zhongdalu/gf.
     6  
     7  package gmvc
     8  
     9  import (
    10  	"github.com/zhongdalu/gf/g/frame/gins"
    11  	"github.com/zhongdalu/gf/g/net/ghttp"
    12  	"github.com/zhongdalu/gf/g/os/gview"
    13  	"sync"
    14  )
    15  
    16  // 基于控制器注册的MVC视图基类(一个请求一个视图对象,用完即销毁)
    17  type View struct {
    18  	mu       sync.RWMutex    // 并发互斥锁
    19  	view     *gview.View     // 底层视图对象
    20  	data     gview.Params    // 视图数据/模板变量
    21  	response *ghttp.Response // 数据返回对象
    22  }
    23  
    24  // 创建一个MVC请求中使用的视图对象
    25  func NewView(w *ghttp.Response) *View {
    26  	return &View{
    27  		view:     gins.View(),
    28  		data:     make(gview.Params),
    29  		response: w,
    30  	}
    31  }
    32  
    33  // 批量绑定模板变量,即调用之后每个线程都会生效,因此有并发安全控制
    34  func (view *View) Assigns(data gview.Params) {
    35  	view.mu.Lock()
    36  	for k, v := range data {
    37  		view.data[k] = v
    38  	}
    39  	view.mu.Unlock()
    40  }
    41  
    42  // 绑定模板变量,即调用之后每个线程都会生效,因此有并发安全控制
    43  func (view *View) Assign(key string, value interface{}) {
    44  	view.mu.Lock()
    45  	view.data[key] = value
    46  	view.mu.Unlock()
    47  }
    48  
    49  // 解析模板,并返回解析后的内容
    50  func (view *View) Parse(file string) (string, error) {
    51  	view.mu.RLock()
    52  	defer view.mu.RUnlock()
    53  	buffer, err := view.response.ParseTpl(file, view.data)
    54  	return buffer, err
    55  }
    56  
    57  // 直接解析模板内容,并返回解析后的内容
    58  func (view *View) ParseContent(content string) (string, error) {
    59  	view.mu.RLock()
    60  	defer view.mu.RUnlock()
    61  	buffer, err := view.response.ParseTplContent(content, view.data)
    62  	return buffer, err
    63  }
    64  
    65  // 使用自定义方法对模板变量执行加锁修改操作
    66  func (view *View) LockFunc(f func(data gview.Params)) {
    67  	view.mu.Lock()
    68  	defer view.mu.Unlock()
    69  	f(view.data)
    70  }
    71  
    72  // 使用自定义方法对模板变量执行加锁读取操作
    73  func (view *View) RLockFunc(f func(data gview.Params)) {
    74  	view.mu.RLock()
    75  	defer view.mu.RUnlock()
    76  	f(view.data)
    77  }
    78  
    79  // 解析并显示指定模板
    80  func (view *View) Display(file ...string) error {
    81  	name := "index.tpl"
    82  	if len(file) > 0 {
    83  		name = file[0]
    84  	}
    85  	if content, err := view.Parse(name); err != nil {
    86  		view.response.Write("Tpl Parsing Error: " + err.Error())
    87  		return err
    88  	} else {
    89  		view.response.Write(content)
    90  	}
    91  	return nil
    92  }
    93  
    94  // 解析并显示模板内容
    95  func (view *View) DisplayContent(content string) error {
    96  	if content, err := view.ParseContent(content); err != nil {
    97  		view.response.Write("Tpl Parsing Error: " + err.Error())
    98  		return err
    99  	} else {
   100  		view.response.Write(content)
   101  	}
   102  	return nil
   103  }