Opa:如何在不阻塞 UI 的情况下与数据库交互

发布于 2024-12-09 08:58:35 字数 1189 浏览 1 评论 0原文

设置

我有一个(相当标准的)表单,允许用户通过输入用户名和密码来创建帐户。当#username 字段失去焦点时,将查询数据库以查看提供的用户名是否可用。

问题

一切都按预期工作,但是当触发#usernameonblur 事件时,用户界面会被阻止,直到数据库返回一个值。如何以异步和非阻塞的方式检查数据库?

这是我的代码(我从示例 Opa 项目中提取了大部分代码):

类型

@abstract type User.ref = string

type User.t = 
  { username : string
  ; passwd : string
  }

type User.map('a) = ordered_map(User.ref, 'a, String.order)

数据库

db /user : User.map(User.t)

表单

<form>
  <input id=#username type="text" onblur={_ -> username_available() } placeholder="username" />
  <input id=#password type="password" placeholder="password" />
</form>

操作

username_available() : void =
  user = Dom.get_value(#username)
  match (get_user(user)) with
  | { none } -> Log.notice("username available:", "YES")
  | { some = _ } -> Log.notice("username available:", "NO")

get_user(username : string) : option(User.t) =
  match ?/user[username] with
  | { none } -> Option.none
  | { ~some } -> Option.some(some)

感谢您的帮助。

The Setup

I have a (rather standard) form that allows a user to create an account by entering a username and password. When the #username field loses focus, the database is queried to see if the supplied username is available.

The Problem

Everything works as expected, but the user interface is blocked from when the onblur event of #username is triggered until the database returns a value. How can check the database in an asyncronous and non-blocking fashion?

Here's my code (I've pulled most of this code out of example Opa projects):

Types

@abstract type User.ref = string

type User.t = 
  { username : string
  ; passwd : string
  }

type User.map('a) = ordered_map(User.ref, 'a, String.order)

Database

db /user : User.map(User.t)

Form

<form>
  <input id=#username type="text" onblur={_ -> username_available() } placeholder="username" />
  <input id=#password type="password" placeholder="password" />
</form>

Actions

username_available() : void =
  user = Dom.get_value(#username)
  match (get_user(user)) with
  | { none } -> Log.notice("username available:", "YES")
  | { some = _ } -> Log.notice("username available:", "NO")

get_user(username : string) : option(User.t) =
  match ?/user[username] with
  | { none } -> Option.none
  | { ~some } -> Option.some(some)

Thanks for your help.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

笑饮青盏花 2024-12-16 08:58:35

非常好的问题。答案非常简单:在 username_available 函数之前添加 @async 指令。它仍然处于实验阶段,因此没有记录。欢迎任何反馈!

附言。一个细节,但如果您包含简单的代码,我个人宁愿一次性看到完整的列表(更容易复制、粘贴和运行);可能用注释代替标题。

Very good question. The answer is quite simple: add @async directive before your username_available function. It is still somewhat experimental and therefore not documented. Any feedback welcome!

PS. A detail, but if you include simple code, personally I'd rather see a complete listing in one go (easier to copy&paste&run); possibly with comments in place of headers.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文