(原) Golang库:go-app 续:实例

原创文章,请后转载,并注明出处。
package main

import (
	"fmt"
	"io/ioutil"
	"net/http"
	"net/url"
	"strconv"

	"github.com/maxence-charriere/go-app/v7/pkg/app"
)

// 线程调用 -------------------------------------------------------

type httpCall struct {
	app.Compo
	response string
}

func (c *httpCall) Render() app.UI {
	return app.Div().Body(
		app.H1().
			Class("title").
			Text("HTTP Call"),

		app.H2().Text("URL:"),
		app.Input().
			Placeholder("Enter an URL").
			OnChange(c.OnURLChange),

		app.H2().Text("Response:"),
		app.P().Text(c.response),
	)
}

func (c *httpCall) OnURLChange(ctx app.Context, e app.Event) {
	c.response = ""
	c.Update()

	url := ctx.JSSrc.Get("value").String()
	go c.doRequest(url)
}

func (c *httpCall) doRequest(url string) {
	r, err := http.Get(url)
	if err != nil {
		c.updateResponse(err.Error())
		return
	}
	defer r.Body.Close()

	b, err := ioutil.ReadAll(r.Body)
	if err != nil {
		c.updateResponse(err.Error())
		return
	}

	c.updateResponse(string(b))
}

func (c *httpCall) updateResponse(res string) {
	app.Dispatch(func() { // 确保响应字段在UI goroutine上更新
		c.response = res
		c.Update()
	})
}

// 选择 --------------------------------------------------------------------------

type ShowSelect struct {
	app.Compo
	option string
}

func (s *ShowSelect) Render() app.UI {
	return app.Div().Body(
		app.Main().Body(
			app.H1().Body(
				app.If(s.option == "",
					app.Text("请选择!"),
				).Else(
					app.Text("你选择了 "+s.option),
				),
			),
		),
		app.Select().Body(
			app.Option().Body(
				app.Text("苹果"),
			),
			app.Option().Body(
				app.Text("橙子"),
			),
			app.Option().Body(
				app.Text("香蕉"),
			),
		).OnChange(s.OnSelectChange),
	)
}

func (s *ShowSelect) OnSelectChange(ctx app.Context, e app.Event) {
	s.option = ctx.JSSrc.Get("value").String()
	s.Update()
}

// 判断 -------------------------------------------------------------

type ScoreUI struct {
	app.Compo
	score int
}

func (c *ScoreUI) Render() app.UI {
	return app.Div().Body(
		app.If(c.score >= 90,
			app.H1().
				Style("color", "green").
				Body(
					app.Text("优!"),
				),
		).ElseIf(c.score >= 60,
			app.H1().
				Style("color", "orange").
				Body(
					app.Text("良!"),
				),
		).Else(
			app.H1().
				Style("color", "red").
				Body(
					app.Text("差!"),
				),
		),
		app.Input().
			Value(c.score).
			Placeholder("Input your score?").
			AutoFocus(true).
			OnChange(c.OnInputChange),
	)
}

func (c *ScoreUI) OnInputChange(ctx app.Context, e app.Event) {
	score, _ := strconv.ParseUint(ctx.JSSrc.Get("value").String(), 10, 32)
	c.score = int(score)
	c.Update()
}

// 列表 -------------------------------------------------------------

type RangeUI struct {
	app.Compo
	name string
}

func (*RangeUI) Render() app.UI {
	langs := []string{"Go", "JavaScript", "Python", "C"}
	return app.Ul().Body(
		app.Range(langs).Slice(func(i int) app.UI {
			return app.Li().Body(
				app.Text(langs[i]),
			)
		}),
	)
}

// 上下文菜单 -------------------------------------------------------------

type ContextMenuUI struct {
	app.Compo
	name string
}

func (c *ContextMenuUI) Render() app.UI {
	return app.Div().Body(
		app.Text("鼠标右键看菜单"),
	).OnContextMenu(c.OnContextMenu)
}

func (*ContextMenuUI) OnContextMenu(ctx app.Context, e app.Event) {
	e.PreventDefault()

	app.NewContextMenu(
		app.MenuItem().
			Label("item 1").
			OnClick(func(ctx app.Context, e app.Event) {
				fmt.Println("item 1 clicked")
			}),
		app.MenuItem().Separator(),
		app.MenuItem().
			Label("item 2").
			OnClick(func(ctx app.Context, e app.Event) {
				fmt.Println("item 2 clicked")
			}),
	)
}

// 生命周期 -------------------------------------------------------------

type Foo struct {
	app.Compo
}

func (*Foo) Render() app.UI {
	return app.P().Body(
		app.Text("Hello World"),
	)
}

func (*Foo) OnMount() {
	fmt.Print("component mounted")
}

func (*Foo) OnNav(u *url.URL) {
	fmt.Print("component navigated:", u)
}

func (*Foo) OnDismount() {
	fmt.Print("component dismounted")
}

//-------------------------------------------------------------

func main() {
	app.Route("/", &httpCall{})       //线程调用
	app.Route("/1", &ShowSelect{})    //选择
	app.Route("/2", &ScoreUI{})       //判断
	app.Route("/3", &RangeUI{})       //列表
	app.Route("/4", &ContextMenuUI{}) //上下文菜单
	app.Route("/5", &Foo{})           //生命周期
	app.Run()
}

相关文章