Opa:如何在不阻塞 UI 的情况下与数据库交互
设置
我有一个(相当标准的)表单,允许用户通过输入用户名和密码来创建帐户。当#username
字段失去焦点时,将查询数据库以查看提供的用户名是否可用。
问题
一切都按预期工作,但是当触发#username
的onblur
事件时,用户界面会被阻止,直到数据库返回一个值。如何以异步和非阻塞的方式检查数据库?
这是我的代码(我从示例 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
非常好的问题。答案非常简单:在
username_available
函数之前添加@async
指令。它仍然处于实验阶段,因此没有记录。欢迎任何反馈!附言。一个细节,但如果您包含简单的代码,我个人宁愿一次性看到完整的列表(更容易复制、粘贴和运行);可能用注释代替标题。
Very good question. The answer is quite simple: add
@async
directive before yourusername_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.