vil*_*asv 8 javascript html5 f# fable-f#
我已经看到了使用HTML5 File API从JavaScript文件输入中读取内容的简单方法.
这是我的view
方法,在一个小 fable-arch
应用程序中:
let view model =
div [
attribute "class" "files-form"
] [
form [
attribute "enctype" "multipart/form-data"
attribute "action" "/feed"
attribute "method" "post"
] [
label [ attribute "for" "x_train" ] [ text "Training Features" ]
input [
attribute "id" "x_train"
attribute "type" "file"
onInput (fun e -> SetTrainingFeaturesFile (unbox e?target?value))
]
]
model |> sprintf "%A" |> text
]
Run Code Online (Sandbox Code Playgroud)
我找不到一种不写纯JavaScript的方法,主要是因为我无法
FileReader
从Fable 导入/实例化 .如果有人可以做到,那么解决方案可能会有所改善.
读取文件是异步的.这意味着视图应生成延迟模型更新.由于这只能在模型更新功能中完成,因此我必须在其中转发JavaScript文件句柄.
纯JavaScript只是一个导出黑客
// file interops.js, can I get rid of this?
export var getReader = function() { return new FileReader(); }
Run Code Online (Sandbox Code Playgroud)
在视图中
// view code
input [
attribute "id" "x_train"
attribute "type" "file"
onInput (fun e -> FromFile (SetField, e?target?files?(0)))
]
Run Code Online (Sandbox Code Playgroud)
因此,该消息实际上是"带有文件内容的延迟消息".这是动作和更新代码:
type Action =
| SetField of string
| FromFile of (string -> Action) * obj
let update model action =
match action with
| SetField content ->
{ model with Field = content}, []
| FromFile (setAction, file) ->
let delayedAction h =
let getReader = importMember "../src/interops.js"
let reader = getReader()
reader?onload <- (fun () -> h <| setAction !!reader?result)
reader?readAsText file |> ignore
model, delayedAction |> toActionList
Run Code Online (Sandbox Code Playgroud)
这FromFile
是一个复杂的动作,因为我想用它来设置多个字段.如果你只需要一个,你可以只做一个of obj
.
在最新版本的《神鬼寓言》中,我们现在可以访问Browser.Dom.FileReader
并避免使用互操作。
可以这样写:
input
[
Class "input"
Type "file"
OnInput (fun ev ->
let file = ev.target?files?(0)
let reader = Browser.Dom.FileReader.Create()
reader.onload <- fun evt ->
dispatch (SaveFileContent evt.target?result)
reader.onerror <- fun evt ->
dispatch ErrorReadingFile
reader.readAsText(file)
)
]
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
659 次 |
最近记录: |