如何在Elm lang 0.17中实现去抖动自动保存?

时间:2016-09-22 09:55:32

标签: elm autosave debouncing

我有以下情况:

当用户停止在文本区域输入时,我想等待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 个答案:

答案 0 :(得分:0)

实现这种行为的一种方法是......

  1. 挂钩onInput活动
  2. onInput处理程序中, 创建一个2秒后触发的任务, 当前值为textarea。 还存储textarea内容。
  3. 检查值是否有 是否更改,如果值没有改变,请保存。
  4. 此处,它不会取消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 ]
      ]