gleam中使用remote data显示数据
gleam简介
gleam是一个强类型语言,可以编译为erlang和javascript,可用作前、后端开发。作为后端,具有高可靠性、高并发特征,可以无缝操作erlang、elixir等语言库;同时作为前端,不用安装太多依赖,直接开箱即用。下面以一个小例子演示gleam的简单用法。
创建工程
gleam new remote
添加依赖
gleam add lustre
gleam add lustre_http
gleam add remote_data
gleam add --dev lustre_dev_tools
创建数据类型
type Quote {
Quote(author: String, content: String)
}
创建模型
type Model {
Model(quote: RemoteData(Quote, HttpError))
}
创建消息
pub opaque type Msg {
UserClickedRefresh
ApiUpdatedQuote(Result(Quote, HttpError))
}
更新
fn get_quote() -> Effect(Msg) {
let url = "https://api.quotable.io/random"
let decoder =
dynamic.decode2(
Quote,
dynamic.field("author", dynamic.string),
dynamic.field("content", dynamic.string),
)
lustre_http.get(url, lustre_http.expect_json(decoder, ApiUpdatedQuote))
}
fn update(_model: Model, msg: Msg) -> #(Model, Effect(Msg)) {
case msg {
UserClickedRefresh -> #(Model(quote: rd.Loading), get_quote())
ApiUpdatedQuote(quote) -> #(
Model(quote: rd.from_result(quote)),
effect.none(),
)
}
}
视图
fn view(model: Model) -> Element(Msg) {
let Model(quote) = model
case quote {
rd.Success(quote) ->
html.div([], [
html.p([on_click(UserClickedRefresh)], [
element.text("Click to refresh quote of the day..."),
]),
element.text(quote.author <> " once said..."),
html.p([attribute.style([#("font-style", "italic")])], [
element.text(quote.content),
]),
])
rd.NotAsked ->
html.p([on_click(UserClickedRefresh)], [
element.text("Click to fetch quote of the day..."),
])
rd.Loading -> html.p([], [element.text("Fetching quote...")])
rd.Failure(_) -> html.p([], [element.text("Failed to fetch quote!")])
}
}
完整代码
import gleam/dynamic
import remote_data.{type RemoteData} as rd
import lustre
import lustre/attribute
import lustre/effect.{type Effect}
import lustre/element.{type Element}
import lustre/element/html
import lustre/event.{on_click}
import lustre_http.{type HttpError}
pub fn main() {
let app = lustre.application(init, update, view)
let assert Ok(_) = lustre.start(app, "#app", Nil)
Nil
}
type Model {
Model(quote: RemoteData(Quote, HttpError))
}
type Quote {
Quote(author: String, content: String)
}
fn init(_) -> #(Model, Effect(Msg)) {
#(Model(quote: rd.NotAsked), effect.none())
}
pub opaque type Msg {
UserClickedRefresh
ApiUpdatedQuote(Result(Quote, HttpError))
}
fn update(_model: Model, msg: Msg) -> #(Model, Effect(Msg)) {
case msg {
UserClickedRefresh -> #(Model(quote: rd.Loading), get_quote())
ApiUpdatedQuote(quote) -> #(
Model(quote: rd.from_result(quote)),
effect.none(),
)
}
}
fn get_quote() -> Effect(Msg) {
let url = "https://api.quotable.io/random"
let decoder =
dynamic.decode2(
Quote,
dynamic.field("author", dynamic.string),
dynamic.field("content", dynamic.string),
)
lustre_http.get(url, lustre_http.expect_json(decoder, ApiUpdatedQuote))
}
fn view(model: Model) -> Element(Msg) {
let Model(quote) = model
case quote {
rd.Success(quote) ->
html.div([], [
html.p([on_click(UserClickedRefresh)], [
element.text("Click to refresh quote of the day..."),
]),
element.text(quote.author <> " once said..."),
html.p([attribute.style([#("font-style", "italic")])], [
element.text(quote.content),
]),
])
rd.NotAsked ->
html.p([on_click(UserClickedRefresh)], [
element.text("Click to fetch quote of the day..."),
])
rd.Loading -> html.p([], [element.text("Fetching quote...")])
rd.Failure(_) -> html.p([], [element.text("Failed to fetch quote!")])
}
}
编译及运行
gleam run -m lustre/dev start

浙公网安备 33010602011771号