2016-09-22 71 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 ] 
    ]