首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用Fable获取文件输入内容

使用Fable获取文件输入内容
EN

Stack Overflow用户
提问于 2017-01-01 21:19:18
回答 3查看 1.5K关注 0票数 11

我见过简单方式使用HTML5 5 using从JavaScript中的文件输入读取更多的内容。

这是我的view方法,在一个小型fable-arch应用程序中:

代码语言:javascript
复制
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
    ]
  • 有没有一种简单的方法可以直接从F#获取文件内容?
  • 实现这一目标所必需的最小数量的互操作寓言代码是什么?
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2020-02-07 10:27:33

在最新版本的寓言中,我们现在可以访问Browser.Dom.FileReader并避免使用互操作。

可以编写这样的东西:

代码语言:javascript
复制
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)
        ) 
    ]

现场演示

票数 8
EN

Stack Overflow用户

发布于 2017-01-03 15:03:10

我找不到一种不编写普通JavaScript的方法,主要是因为我无法从Fable导入/实例化FileReader。如果有人能做到这一点,那么解决方案可能会改进。

读取文件是异步的。这意味着视图应该生成一个延迟更新的模型。因为这只能在模型更新函数中完成,所以我不得不在里面转发一个JavaScript文件句柄。

普通的JavaScript只是一个出口黑客。

代码语言:javascript
复制
// file interops.js, can I get rid of this?
export var getReader = function() { return new FileReader(); }

在视野中

代码语言:javascript
复制
// view code
input [
    attribute "id" "x_train"
    attribute "type" "file"
    onInput (fun e -> FromFile (SetField, e?target?files?(0)))
]

因此,该消息实际上是“带有文件内容的延迟消息”。下面是操作和更新代码:

代码语言:javascript
复制
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

FromFile是一个复杂的操作,因为我想使用它来设置多个新字段。如果你只需要一个,你可以让它只是一个of obj

票数 10
EN

Stack Overflow用户

发布于 2021-05-23 00:00:28

下面是我对Maxime的答案的看法,使用Fable.Elmish.React v3.0.1。我不熟悉这个?运算符,但我可以使用:?> one来转换某些类型。

代码语言:javascript
复制
input [
          Class "input"
          Type "file"
          OnInput (fun ev ->
            let file = (ev.target :?> Browser.Types.HTMLInputElement).files.Item(0)
            let reader = Browser.Dom.FileReader.Create()
            reader.onload <- fun evt ->
              (*
                Negotiate/assume the onload target is a FileReader
                Result is a string containg file contents:
                https://developer.mozilla.org/en-US/docs/Web/API/FileReader/readAsText
              *)
              dispatch (Set (string (evt.target :?> Browser.Types.FileReader).result))

            reader.onerror <- fun evt ->
              dispatch (Set "Error")
            
            reader.readAsText(file))]
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41419120

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档