• 教程九 在Go中使用Energy创建跨平台GUI应用 - Go绑定变量JS调用


     


     

    介绍

    Energy Go中定义的变量、结构和函数绑定,在JS中使用。

    在Energy中不只可以调用 JS 和 事件机制,也可以通过Go绑定在Go中定义的一些变量函数在JS中调用,在使用的时候就如同在JS调用本身定义的函数一样方便。

    运行此示例,需要安装好Go和Energy开发环境:教程一 环境安装

    此示例中采用了内置http服务访问内嵌资源: 内置http服务


    使用方式

    在Go中绑定使用cef.VariableBind.VariableCreateCallback变量创建初始化函数绑定,

    支持类型,目前只支持 String, Integer, Boollean, Double(float64), null, undefiend, function
    不支持类型 Object, Array

    绑定的变量区分为通用类型和结构类型,每个类型都有自己的根对象,在window下为

    结构类型: window.goobj
    通用类型: window.gocobj
    在应用初始化时通过ApplicationConfig对象的SetCommonRootName和SetObjectRootName设置根对象名称

    字段取赋值,函数调用

    在html中取值、赋值、函数调用

    通用类型和结构类型取赋值方式一样,直接通过变量名

    字段取值 var demoVar = goobj.demo

    字段赋值 goobj.demo='新值'

    函数调用 goobj.funcName(xxx,xxx)

    通用类型

    在绑定变量初始化函数中使用bind.NewXXXX(“name”,[初始值])
    通用类型变量可任意更改变量值的类型,在GO中使用时需要类型判断,否则取值失败。
    变量值存放在主进程(browser)中,与渲染进程共享。
    在Go和Web中共享这些变量可直接修改

    结构类型

    在绑定变量初始化函数中使用bind.NewObjects(…array)进行结构类型绑定
    在Go中定义的struts类型, 该类型变量类型不可更改
    变量值存放在主进程(browser)中,与渲染进程共享。
    在Go和Web中共享这些变量可直接修改
    结构内定义的字段为绑定的字段,首字母需大写,否则绑定不成功。

    函数类型

    结构类型和通用类型都可定义函数,函数名需首字母大写
    入参最多9个,可带有1个返回值

    Go代码示例

    示例中,在cef.VariableBind.VariableCreateCallback变量绑定函数中对通用类型变量和结构类型进行了绑定

    通用类型,使用bind.NewXXX的方式

    结构类型,使用bind.NewObjects的方式

    main.go

    1. package main
    2. import (
    3. "embed"
    4. "fmt"
    5. "github.com/energye/energy/cef"
    6. "github.com/energye/energy/common/assetserve"
    7. "github.com/energye/energy/example/browser-go-bind-js-var/src"
    8. )
    9. //go:embed resources
    10. var resources embed.FS
    11. func main() {
    12. //全局初始化 每个应用都必须调用的
    13. cef.GlobalCEFInit(nil, &resources)
    14. //创建应用
    15. cefApp := cef.NewApplication(nil)
    16. //指定一个URL地址,或本地html文件目录
    17. cef.BrowserWindow.Config.DefaultUrl = "http://localhost:22022/go-bind-js-var.html"
    18. cef.BrowserWindow.Config.Title = "Energy - execute-javascript"
    19. cef.BrowserWindow.Config.Icon = "resources/icon.ico"
    20. //内置http服务链接安全配置
    21. cef.SetBrowserProcessStartAfterCallback(func(b bool) {
    22. fmt.Println("主进程启动 创建一个内置http服务")
    23. //通过内置http服务加载资源
    24. server := assetserve.NewAssetsHttpServer()
    25. server.PORT = 22022
    26. server.AssetsFSName = "resources" //必须设置目录名
    27. server.Assets = &resources
    28. go server.StartHttpServer()
    29. })
    30. //变量创建回调-这个函数在主进程(browser)和子进程(render)中执行
    31. //变量的值绑定到主进程
    32. cef.VariableBind.VariableCreateCallback(func(browser *cef.ICefBrowser, frame *cef.ICefFrame, bind cef.IProvisionalBindStorage) {
    33. //初始化要绑定的变量
    34. //结构类型
    35. src.JSStructVarDemo = &src.StructVarDemo{}
    36. src.JSStructVarDemo.StringField = "初始的字符串值"
    37. bind.NewObjects(src.JSStructVarDemo)
    38. //通用类型
    39. src.JSString = bind.NewString("JSString", "初始的字符串值")
    40. src.JSInt = bind.NewInteger("JSInt", 0)
    41. src.JSBool = bind.NewBoolean("JSBool", false)
    42. src.JSDouble = bind.NewDouble("JSDouble", 0.0)
    43. _ = bind.NewFunction("JSFunc", src.JSFunc)
    44. })
    45. //运行应用
    46. cef.Run(cefApp)
    47. }

    src/common-var.go

    定义了通用类型变量

    1. package src
    2. import (
    3. "fmt"
    4. "github.com/energye/energy/cef"
    5. )
    6. var (
    7. JSString *cef.JSString
    8. JSInt *cef.JSInteger
    9. JSBool *cef.JSBoolean
    10. JSDouble *cef.JSDouble
    11. )
    12. func JSFunc(p1 string) string {
    13. fmt.Println("Go中执行JSFunc 参数:", p1)
    14. var ret string
    15. //类型判断
    16. if JSString.IsString() {
    17. ret = JSString.Value()
    18. } else if JSString.IsInteger() {
    19. //web js 中改变成integer类型
    20. intVal, _ := JSString.IntegerValue()
    21. ret = fmt.Sprintf("%d", intVal)
    22. }
    23. fmt.Println("JSString:", ret, "JSInt:", JSInt.Value(), "JSBool:", JSBool.Value(), "JSDouble:", JSDouble.Value())
    24. return p1 + " Go返回的值: " + ret
    25. }

    src/struct-var.go

    定义了结构

    1. package src
    2. import "fmt"
    3. var JSStructVarDemo *StructVarDemo
    4. //定义结构类型的变量
    5. //结构类型将属性和函数导出为JS可调用类型
    6. //大写字母开头
    7. type StructVarDemo struct {
    8. StringField string
    9. IntField int32
    10. BoolField bool
    11. FloatField float64
    12. noExportField string //小写字母无法绑定到js
    13. }
    14. //结构类型的函数导出
    15. func (m *StructVarDemo) StringValue(p0 string) string {
    16. fmt.Println("结构类型绑定函数 StringValue 被调用 入参:", p0)
    17. return m.StringField + p0
    18. }
    19. //结构类型的函数导出
    20. func (m *StructVarDemo) IntValue(intParam int32) int32 {
    21. fmt.Println("结构类型绑定函数 IntValue 被调用 入参:", intParam)
    22. return m.IntField + intParam
    23. }
    24. //定义导出函数参数最多为9个
    25. func (m *StructVarDemo) FuncMaxParam(p1, p2, p3, p4, p5, p6, p7, p8, p9 string) {
    26. fmt.Println("结构类型绑定函数 FuncMaxParam 被调用 入参:", p1, p2, p3, p4, p5, p6, p7, p8, p9)
    27. }

    html代码示例

    在html中直接使用根对象调用函数

    通用类型 gocobj.XXX

    结构类型 goobj.XXX

    通用类型可任意改变值类型(所支持的类型)

    结构类型不可改变值类型(只能是go中定义的类型)

    1. html>
    2. <html lang="en">
    3. <head>
    4. <meta charset="UTF-8">
    5. <title>execute-go-bind-js-vartitle>
    6. <script type="application/javascript">
    7. function clearMessage() {
    8. document.getElementById("message").innerHTML = "";
    9. }
    10. function writeMessage(data) {
    11. let message = document.getElementById("message");
    12. message.innerHTML = message.innerHTML + data + "
      "
    13. }
    14. //通过根对象 goobj 和 gocobj 获取或设置值
    15. //goobj 是结构类型的根对象
    16. //gocobj 是通用类型的根对象
    17. /** 结构类型 */
    18. //获取Go中定义的绑定变量值
    19. function getGoBindVar() {
    20. clearMessage()
    21. writeMessage("结构")
    22. //------------------------
    23. //获取结构类型的字段值 string
    24. writeMessage("StringField: " + goobj.StructVarDemo.StringField)
    25. writeMessage("IntField: " + goobj.StructVarDemo.IntField)
    26. writeMessage("BoolField: " + goobj.StructVarDemo.BoolField)
    27. writeMessage("FloatField: " + goobj.StructVarDemo.FloatField)
    28. try {
    29. writeMessage("noExportField 是未导出的字段,将获取失败")
    30. writeMessage("noExportField: " + goobj.StructVarDemo.noExportField)
    31. } catch (e) {
    32. writeMessage("异常: " + e)
    33. }
    34. }
    35. //设置Go中定义的绑定变量值
    36. function setGoBindVar() {
    37. clearMessage()
    38. writeMessage("结构")
    39. //设置结构类型的字段值 string
    40. //注意: 结构类型的字段,设置不同类型的值将出现JS异常
    41. goobj.StructVarDemo.StringField = "在Web中改变后的值"
    42. goobj.StructVarDemo.IntField = 999999
    43. goobj.StructVarDemo.BoolField = true
    44. goobj.StructVarDemo.FloatField = 99999.9999
    45. try {
    46. writeMessage("StringField=int 不同的类型赋值将出现异常")
    47. //不同的类型赋值将出现异常
    48. goobj.StructVarDemo.StringField = 1001
    49. } catch (e) {
    50. writeMessage("异常: " + e)
    51. }
    52. }
    53. //调用Go中定义的函数
    54. function callGoBindFunc() {
    55. clearMessage()
    56. writeMessage("结构")
    57. //在JS中调用Go的函数
    58. //注意:同字段一样函数首字母只有大写才能调用
    59. // 入参类型必须符合Go中函数定义的参数类型, 否则调用失败, 注意的是参数个数有限制
    60. let ret = goobj.StructVarDemo.StringValue(' JS传的入参')
    61. writeMessage("调用函数 StringValue(param0 string) string: " + ret)
    62. goobj.StructVarDemo.FuncMaxParam('参数1', '参数2', '参数3', '参数4', '参数5', '参数6', '参数7', '参数8', '参数9')
    63. try {
    64. writeMessage("FuncMaxParam 函数和入参个数大于9个调用失败")
    65. //参数个数大于9个调用失败
    66. goobj.StructVarDemo.FuncMaxParam('参数1', '参数2', '参数3', '参数4', '参数5', '参数6', '参数7', '参数8', '参数9', '参数10')
    67. } catch (e) {
    68. writeMessage("异常: " + e)
    69. }
    70. }
    71. /** 普通类型 */
    72. //获取通用变量类型值
    73. function getGoBindCVar() {
    74. clearMessage()
    75. writeMessage("通用类型")
    76. writeMessage('JSString: ' + gocobj.JSString)
    77. writeMessage('JSInt: ' + gocobj.JSInt)
    78. writeMessage('JSBool: ' + gocobj.JSBool)
    79. writeMessage('JSDouble: ' + gocobj.JSDouble)
    80. }
    81. function setGoBindCVar() {
    82. clearMessage()
    83. writeMessage("通用类型")
    84. //通用类型可以任意修改变量存放的值类型
    85. gocobj.JSString = 'JS中改变了通用类型字符串值'
    86. writeMessage('JSString值改变: ' + gocobj.JSString)
    87. //改变为其它类型后,在Go中使用时需要判断类型,否则类型不一样无法正确取值
    88. gocobj.JSString = 99999
    89. writeMessage('JSString值变成了Int类型: ' + gocobj.JSString)
    90. //将其它变量值改变
    91. gocobj.JSInt = 999911
    92. gocobj.JSBool = true
    93. gocobj.JSDouble = 999999.999
    94. }
    95. function callGoBindCFunc() {
    96. clearMessage()
    97. writeMessage("通用类型")
    98. writeMessage('调用JSFunc函数: ' + gocobj.JSFunc('JS传入的参数'))
    99. }
    100. /** to json */
    101. function toJSON() {
    102. clearMessage()
    103. writeMessage("ToJSON")
    104. writeMessage('结构类型-JSON: ' + JSON.stringify(goobj))
    105. writeMessage('通用类型-JSON: ' + JSON.stringify(gocobj))
    106. }
    107. script>
    108. head>
    109. <body style="overflow: hidden;margin: 0px;padding: 0px;">
    110. execute-go-bind-js-var:<br>
    111. <div style="margin: 10px">
    112. 结构类型:
    113. <button onclick="getGoBindVar()">获取Go中定义的绑定变量值button>
    114. <button onclick="setGoBindVar()">设置Go中定义的绑定变量值button>
    115. <button onclick="callGoBindFunc()">调用Go中定义的函数button>
    116. div>
    117. <div style="margin: 10px">
    118. 通用类型:
    119. <button onclick="getGoBindCVar()">获取Go中定义的通用类型绑定变量值button>
    120. <button onclick="setGoBindCVar()">设置Go中定义的通用类型绑定变量值button>
    121. <button onclick="callGoBindCFunc()">调用Go中定义的函数button>
    122. div>
    123. <div style="margin: 10px">
    124. <button onclick="toJSON()">toJSONbutton>
    125. div>
    126. <div id="message">div>
    127. body>
    128. html>

    效果图

     

  • 相关阅读:
    6-Dubbo架构设计与底层原理-服务导出源码分析(下)
    css自学框架之选项卡
    通过easyexcel导出数据到excel表格
    OSCP-Vulnhub靶机记录-hacker-kid-walkthrough
    Memcached对象缓存详解
    少即是多:视觉SLAM的点稀疏化(IROS 2022)
    springboot(14):WebMvcConfigurer配置类
    【Vue + Koa 前后端分离项目实战3】使用开源框架==>快速搭建后台管理系统 -- part3 权限控制+行为日志
    要想不踩SaaS那些坑,得先了解“SaaS架构”
    java jedis连接redis数据库实战
  • 原文地址:https://blog.csdn.net/snxamdf/article/details/128129771