通过用户操作取消函数 (html/template)
Cancelling function by user action (html/template)
我的目标是:
- 有一个带有
<a href>
到 enable/disable 功能的 html 页面
- 启用后:调用函数:在我的示例中为总和
- 禁用时:停止/终止之前调用的函数
前两点就可以了(或者随时告诉我我可以改进的地方)
但是我不知道第三点怎么做(因为我做第一点的方法不好?)
package main
import (
"html/template"
"github.com/labstack/echo"
"log"
"io"
"net/http"
"strconv"
"fmt"
"time"
)
//init LOG
func init(){
log.SetPrefix("TRACE: ")
log.SetFlags(log.Ldate | log.Ltime | log.Llongfile)
log.Println("init started")
}
// main function
func main() {
// defining struct instance
settings.Enabled = false
// Parsing the required html
// file in same directory
// Parsing Templates
t := &Template{
templates: template.Must(template.ParseGlob("test.html")),
}
// standard output to print merged data
e := echo.New()
e.Renderer = t
e.HideBanner = false
e.HidePort = false
e.Debug = true
e.GET("/", index)
e.GET("/toggleEnable", toggleEnable)
e.Start("127.0.0.1" + ":" + strconv.Itoa(8080))
}
func index(c echo.Context) error {
return c.Render(http.StatusOK, "index", settings)
}
// Settings Type ...
type Settings struct {
Enabled bool
}
var settings Settings
type Template struct {
templates *template.Template
}
func (t *Template) Render(w io.Writer, name string, data interface{}, c echo.Context) error {
return t.templates.ExecuteTemplate(w, name, data)
}
func toggleEnable(c echo.Context) error {
if settings.Enabled {
settings.Enabled = false
} else {
settings.Enabled = true
Sum()
}
return c.Redirect(http.StatusTemporaryRedirect, c.Request().Header.Get("Referer"))
}
func Sum() {
sum := 0
for i := 1; i < 50; i++ {
sum += i
fmt.Println(sum)
time.Sleep(3 * time.Second)
}
}
和test.html:
```
<!DOCTYPE html>
<html>
<head>
<title>Test</title>
</head>
<body>
{{define "index"}}
<h1>Settings</h1>
<p>Test enabled : <a href="/toggleEnable">{{.Enabled }}</a></p>
{{end}}
</body>
</html>
```
目前,如果我为假 -> 真:求和有效,如果我为真 -> 假:没有任何反应,如果我再次为假 -> 真:另一次计数开始。
下一步将在 html 页面中显示计数。
如当前浏览器请求 /toggleEnable
时所写,在 Sum()
完成之前不会返回任何内容(大约需要 150 秒)。 Sum()
完成后,带有 Test enabled : false
的页面将变为 returned/displayed。如果你想为用户提供中断进程的能力,那么最好在 Goroutine 中 运行 它;像这样:
// Settings Type ...
type Settings struct {
Enabled bool
Stop chan struct{}
}
var settings Settings
type Template struct {
templates *template.Template
}
func (t *Template) Render(w io.Writer, name string, data interface{}, c echo.Context) error {
return t.templates.ExecuteTemplate(w, name, data)
}
func toggleEnable(c echo.Context) error {
if settings.Enabled {
settings.Enabled = false
close(settings.Stop)
} else {
settings.Enabled = true
settings.Stop = make(chan struct{})
go Sum(settings.Stop)
}
return c.Redirect(http.StatusTemporaryRedirect, c.Request().Header.Get("Referer"))
}
func Sum(stop chan struct{}) {
sum := 0
for i := 1; i < 50; i++ {
sum += i
fmt.Println(sum)
select {
case <-stop:
fmt.Println("stopped")
return
case <-time.After(3 * time.Second):
}
}
}
请注意,这有一些问题。它是在假设只有一个客户端并且计时器完成时页面不会更新的假设下编写的(您需要添加刷新或类似的)。
Next step will be to display count in html page
为此,您需要一种浏览器请求更新的方法。这可以通过 refresh(相当简单但不是很好的用户体验)或使用 Javascript(轮询或使用 websockets)实现。
我的目标是:
- 有一个带有
<a href>
到 enable/disable 功能的 html 页面 - 启用后:调用函数:在我的示例中为总和
- 禁用时:停止/终止之前调用的函数
前两点就可以了(或者随时告诉我我可以改进的地方)
但是我不知道第三点怎么做(因为我做第一点的方法不好?)
package main
import (
"html/template"
"github.com/labstack/echo"
"log"
"io"
"net/http"
"strconv"
"fmt"
"time"
)
//init LOG
func init(){
log.SetPrefix("TRACE: ")
log.SetFlags(log.Ldate | log.Ltime | log.Llongfile)
log.Println("init started")
}
// main function
func main() {
// defining struct instance
settings.Enabled = false
// Parsing the required html
// file in same directory
// Parsing Templates
t := &Template{
templates: template.Must(template.ParseGlob("test.html")),
}
// standard output to print merged data
e := echo.New()
e.Renderer = t
e.HideBanner = false
e.HidePort = false
e.Debug = true
e.GET("/", index)
e.GET("/toggleEnable", toggleEnable)
e.Start("127.0.0.1" + ":" + strconv.Itoa(8080))
}
func index(c echo.Context) error {
return c.Render(http.StatusOK, "index", settings)
}
// Settings Type ...
type Settings struct {
Enabled bool
}
var settings Settings
type Template struct {
templates *template.Template
}
func (t *Template) Render(w io.Writer, name string, data interface{}, c echo.Context) error {
return t.templates.ExecuteTemplate(w, name, data)
}
func toggleEnable(c echo.Context) error {
if settings.Enabled {
settings.Enabled = false
} else {
settings.Enabled = true
Sum()
}
return c.Redirect(http.StatusTemporaryRedirect, c.Request().Header.Get("Referer"))
}
func Sum() {
sum := 0
for i := 1; i < 50; i++ {
sum += i
fmt.Println(sum)
time.Sleep(3 * time.Second)
}
}
和test.html:
```
<!DOCTYPE html>
<html>
<head>
<title>Test</title>
</head>
<body>
{{define "index"}}
<h1>Settings</h1>
<p>Test enabled : <a href="/toggleEnable">{{.Enabled }}</a></p>
{{end}}
</body>
</html>
```
目前,如果我为假 -> 真:求和有效,如果我为真 -> 假:没有任何反应,如果我再次为假 -> 真:另一次计数开始。
下一步将在 html 页面中显示计数。
如当前浏览器请求 /toggleEnable
时所写,在 Sum()
完成之前不会返回任何内容(大约需要 150 秒)。 Sum()
完成后,带有 Test enabled : false
的页面将变为 returned/displayed。如果你想为用户提供中断进程的能力,那么最好在 Goroutine 中 运行 它;像这样:
// Settings Type ...
type Settings struct {
Enabled bool
Stop chan struct{}
}
var settings Settings
type Template struct {
templates *template.Template
}
func (t *Template) Render(w io.Writer, name string, data interface{}, c echo.Context) error {
return t.templates.ExecuteTemplate(w, name, data)
}
func toggleEnable(c echo.Context) error {
if settings.Enabled {
settings.Enabled = false
close(settings.Stop)
} else {
settings.Enabled = true
settings.Stop = make(chan struct{})
go Sum(settings.Stop)
}
return c.Redirect(http.StatusTemporaryRedirect, c.Request().Header.Get("Referer"))
}
func Sum(stop chan struct{}) {
sum := 0
for i := 1; i < 50; i++ {
sum += i
fmt.Println(sum)
select {
case <-stop:
fmt.Println("stopped")
return
case <-time.After(3 * time.Second):
}
}
}
请注意,这有一些问题。它是在假设只有一个客户端并且计时器完成时页面不会更新的假设下编写的(您需要添加刷新或类似的)。
Next step will be to display count in html page
为此,您需要一种浏览器请求更新的方法。这可以通过 refresh(相当简单但不是很好的用户体验)或使用 Javascript(轮询或使用 websockets)实现。