2017-01-01 15 views
7

Widziałem simple ways, aby odczytać zawartość z pliku wejściowego w JavaScript przy użyciu API pliku HTML5.Uzyskiwanie zawartości pliku wejściowego za pomocą bajka

To mój view metoda, wewnątrz małego fable-arch aplikacji:

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 
    ] 
  • Czy istnieje prosty sposób na przechwytywanie zawartości pliku bezpośrednio z F #?
  • Jaka jest minimalna ilość kodów interop niezbędnych do osiągnięcia tego?

Odpowiedz

5

nie mogłem znaleźć sposób, aby nie pisać zwykły JavaScript głównie dlatego, że nie mógł importować/instancję FileReader z Fable. Jeśli ktoś może to zrobić, to prawdopodobnie rozwiązanie może się poprawić.

Odczytywanie pliku jest asynchroniczne. Oznacza to, że widok powinien generować opóźnioną aktualizację modelu. Ponieważ można to zrobić tylko w funkcji aktualizacji modelu, musiałem przesłać uchwyt pliku JavaScript wewnątrz.

równinie JavaScript jest tylko eksport włamać

// file interops.js, can I get rid of this? 
export var getReader = function() { return new FileReader(); } 

W widoku

// view code 
input [ 
    attribute "id" "x_train" 
    attribute "type" "file" 
    onInput (fun e -> FromFile (SetField, e?target?files?(0))) 
] 

więc wiadomość jest faktycznie „Opóźniona Wiadomość z zawartością pliku”. Oto działania i zmiana kodu:

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 to kompleks działanie, bo chcę go użyć, aby ustawić więcej niż jedno pole. Jeśli potrzebujesz tylko jednego, możesz zrobić to tylko of obj.

+0

Dzięki @MangelMaxime za wszystkie sugestie na kanale Fable. :-) – VillasV