2016-11-29 2 views
3

Elm에서 수행해야 할 DOM 조작이 많으면 결과가 나타나기 전에 약간의 지연이 있습니다. 느릅 나무가 그 일을하는 동안 "Loading ..."라는 자리 표시 자 div를 표시하는 방법을 찾으려고합니다. 윌 '+'버튼을 클릭 DOM 요소를 렌더링하는 동안 Elm에 'loading placeholder'표시

import Html exposing (beginnerProgram, div, button, text) 
import Html.Events exposing (onClick) 

main = 
    beginnerProgram { model = 0, view = view, update = update } 


view model = 
    div [] 
    [ button [ onClick Decrement ] [ text "-" ] 
    , div [] [ text (toString model) ] 
    , button [ onClick Increment ] [ text "+" ] 
    , div [] (List.repeat (2^model) (text ". ")) -- this is my addition 
    ] 

type Msg = Increment | Decrement 

update msg model = 
    case msg of 
    Increment -> 
     model + 1 

    Decrement -> 
     model - 1 

이 예를 실행 :

지연을 설명하기 위해, 나는 버튼 클릭시 텍스트 요소의 점점 더 많은 수를 렌더링하는 Elm examples 중 하나를 수정 한 '보여라.' 문자가 2의 배수가됩니다. 숫자가 충분히 높으면 (내 컴퓨터에서 약 16), '.'기호를 클릭 한 후 몇 초 동안 지연됩니다. 문자가 표시됩니다.

'.'요소를 렌더링하기 전에 'loading ...'요소를 ('div'에서 말하면) 표시하는 좋은 방법은 무엇입니까? 집단?

+1

예제 코드에서 볼 수있는 것은 실제로 브라우저입니다 렌더링/레이아웃은 대부분 소비합니다. 대기 시간 중, js 엔진에 의한 가상 DOM의 diffing이 아닌. 느릅 나무 특유의 것으로 보이지 않기 때문에 다른 프레임 워크 (또는 자바 스크립트 DOM API 호출로)가 어떻게 처리 할 수 ​​있는지 조사하고 싶을 수 있습니다. – Tosh

답변

4

당신은 정기적 Html.program를 사용하고 DOM은 "로드"를 렌더링 할 수 있도록 일시 정지됩니다 Increment/Decrement 업데이트 핸들러에서 Cmd을 반환하고 update 다시 입력해야합니다 :

import Html exposing (program, div, button, text) 
import Html.Events exposing (onClick) 
import Process 
import Task 

main = 
    program { init = (Model 0 False, Cmd.none), view = view, update = update, subscriptions = \_ -> Sub.none } 

type alias Model = 
    { count: Int 
    , loading: Bool 
    } 

view model = 
    let 
    dotsDisplay = 
     if model.loading then 
     div [] [text "Loading..."] 
     else 
     div [] (List.repeat (2^model.count) (text ". ")) 
    in 
    div [] 
     [ button [ onClick Decrement ] [ text "-" ] 
     , div [] [ text (toString model.count) ] 
     , button [ onClick Increment ] [ text "+" ] 
     , dotsDisplay 
     ] 

type Msg = Increment | Decrement | FinishLoading 

finishLoadingCmd = 
    Task.map2 (\_ b -> b) (Process.sleep 10) (Task.succeed FinishLoading) 
    |> Task.perform identity 

update msg model = 
    case msg of 
    Increment -> 
     {model | count = model.count + 1, loading = True} ! [finishLoadingCmd] 

    Decrement -> 
     {model | count = model.count - 1, loading = True} ! [finishLoadingCmd] 

    FinishLoading -> 
     {model | loading = False} ! [] 

을 그래도 모든 노드를 렌더링하는 동안 여전히 브라우저를 잠글 것이므로 아마도 100k + DOM 요소를 렌더링하지 않는 방법을 찾고 싶을 것입니다 ...

관련 문제