简化交互代码
1. Api 与 InitApi 的优化
假设我们有一个表单页面,用户输入信息后点击提交,我们需要将信息存入数据库。
传统方式
使用 form
组件的 Api
方法,代码可能如下:
app := amisgo.New()
index := app.Page().Body(
app.Form().Api("/user").Body(
app.InputText().Label("姓名").Name("name"),
app.InputEmail().Label("邮箱").Name("email"),
),
)
app.HandleFunc("/user", func(w http.ResponseWriter, r *http.Request) {
input, _ := io.ReadAll(r.Body)
defer r.Body.Close()
m := map[string]string{}
json.Unmarshal(input, &m)
name := m["name"]
email := m["email"]
fmt.Println(name, email)
// 将用户信息存入数据库 ...
})
优化方式
amisgo
为 form
组件新增了 Submit
方法,简化了代码:
func (f Form) Submit(callback func(schema.Schema) error) Form
优化后的代码如下:
app := amisgo.New()
index := app.Page().Body(
app.Form().Api("/user").Body(
app.InputText().Label("姓名").Name("name"),
app.InputEmail().Label("邮箱").Name("email"),
).Submit(
func(s schema.Schema) error {
name := s.Get("name").(string)
email := s.Get("email").(string)
fmt.Println(name, email)
// 将用户信息存入数据库 ...
return nil
},
),
)
此外,另有
SubmitTo
方法允许使用具体类型处理表单数据:func (f form) SubmitTo(receiver any, callback func(any) error) form
InitData 方法
类似地,page
组件的 InitApi
也有对应的优化方法 InitData
:
func (p page) InitData(getter func() (any, error)) page
例如,获取当前时间的代码可以简化为:
func main() {
app := amisgo.New()
index := app.Page().Body("Now: ${date}").InitData(getDate)
app.Mount("/", index)
app.Run(":8888")
}
func getDate() (any, error) {
y, m, d := time.Now().Date()
mm := time.Now().UnixNano()
return map[string]string{"date": fmt.Sprintf("%d-%d-%d %d", y, m, d, mm)}, nil
}
2. Action 按钮的优化
假设页面有两个输入框,第一个用于输入人名,第二个只读。点击按钮后,将输入做一定转换,并渲染到第二个文本框中。
传统方式
使用 ajax
类型的行为按钮,代码如下:
app := amisgo.New()
index := app.Page().Body(
app.Form().WrapWithPanel(false).Body(
app.InputText().Name("input"),
app.InputText().Name("output").ReadOnly(true),
app.Action().Label("Greet").Level("primary").ActionType("ajax").Api(
app.Api().Url("/convert").Data(schema.Schema{"input": "${input}"}).Set(
"resp",
schema.Schema{
"200": schema.Schema{
"then": app.EventAction().ActionType("setValue").
Args(app.EventActionArgs().Value("${resp}")),
},
},
),
),
),
)
app.Mount("/", index)
app.HandleFunc("/convert", func(w http.ResponseWriter, r *http.Request) {
input, _ := io.ReadAll(r.Body)
defer r.Body.Close()
m := map[string]string{}
json.Unmarshal(input, &m)
output := "hello " + m["input"]
resp := schema.SuccessResponse("", schema.Schema{"output": output}) // 这里的 key 值必须是第二个编辑器的 name
w.Write(resp.Json())
})
优化方式
amisgo
为行为按钮新增了 Transform
方法:
func (a Action) Transform(transfor func(input any) (any, error), src, dst string) Action
优化后的代码如下:
app := amisgo.New()
index := app.Page().Body(
app.Form().WrapWithPanel(false).Body(
app.InputText().Name("input"),
app.InputText().Name("output").ReadOnly(true),
app.Action().Label("Greet").
Level("primary").
Transform(func(input any) (any, error) {
return "hello " + input.(string), nil
}, "input", "output"),
),
)
多对多转换
另有 TransformMultiple
方法支持从多个组件的输入值转换后渲染到多个组件。可以参考“应用案例”章节中的 dev-toys,其中的 convert 组件使用了 Transform,生成多种类型的 hash 值使用了 TransformMultiple。
通过以上优化,代码变得更加简洁易读,减少了冗余的 HTTP 请求处理逻辑,提升了开发效率。