2016-09-22 73 views
1

我有以下情況:如何在Elm lang 0.17中實現去抖自動保存?

當用戶停止在文本區域輸入時,我想等待2秒鐘,如果用戶在2秒內沒有更改textarea中的任何內容,我想要保存textarea的內容到服務器。如果用戶在2秒內改變了textarea中的內容,我想重新啓動等待超時。

在JavaScript中,我會實現它這樣

http://codepen.io/ondrejsevcik/pen/LRxWQP

// Html 
<textarea id="textarea"></textarea> 
<pre id="server"></pre> 

// JavaScript 
var textarea = document.querySelector('#textarea'); 

var textValue = ""; 
textarea.oninput = function (e) { 
    textValue = e.target.value; 
    setSaveTimeout(); 
} 

let saveTimeout; 
function setSaveTimeout() { 
    if (saveTimeout) { 
    clearTimeout(saveTimeout); 
    } 
    saveTimeout = setTimeout(saveToServer, 2000); 
} 

function saveToServer() { 
    document.querySelector('#server').innerText = 
    'Value saved to server: ' + textValue; 
} 
+1

['Process.sleep'](http://package.elm-lang.org/packages/elm-lang/core/4.0.5/Process#sleep)是榆樹的'setTimeout'等效,顯然。我能夠找到[這個例子](https://github.com/fredcy/example-elm-debounce/blob/master/Debounce.elm)使用它來消除,但不管它是否是最好的方式,我我不確定。 –

+1

此外,以下是討論如何反彈的用戶組的一個主題:https://groups.google.com/forum/#!topic/elm-discuss/w4MwjIaTiIY –

回答

0

一種方式來實現行爲的東西是..

  1. 掛鉤onInput事件
  2. onInput處理程序, 創建一個任務fi res 2秒後, ,當前值爲textarea。 還存儲textarea內容。
  3. 檢查值是否有 已更改,如果值未更改,請保存。

在這裏,它不取消Task,所以它可能沒有效率。

-- MODEL 
type alias Model = 
    { str : String 
    , saved : String 
    } 

init : (Model, Cmd Msg) 
init = 
    (Model "" "", Cmd.none) 

-- UPDATE 
type Msg 
    = ChangeText String 
    | Save String 
    | NoOp() 

update : Msg -> Model -> (Model, Cmd Msg) 
update msg model = 
    case msg of 
    NoOp _ -> (model, Cmd.none) 
    Save str -> 
     let 
     _ = Debug.log "save" str 
     newmodel = 
      if model.str /= str 
      then model 
      else { model | saved = str } 
     in (newmodel, Cmd.none)  
    ChangeText str -> 
     let 
     _ = Debug.log "textarea" str 
     cmd = Task.perform NoOp Save <| 
      Process.sleep (2 * Time.second) 
      `Task.andThen` 
      \_ -> Task.succeed str 
     in ({ model | str = str }, cmd) 

-- VIEW 
view : Model -> Html Msg 
view model = 
    Html.div [] 
    [ Html.textarea [ onInput ChangeText ] [] 
    , Html.div [] [ Html.text <| "saved: " ++ model.saved ] 
    ]