2017-09-12 10 views
1

두 개의 이벤트 핸들러를 사용하는 작은 Scala.Js 앱을 작성했습니다. 하나는 입력 필드의 onkeyup 이벤트 용이고 다른 하나는 버튼 onclick 이벤트 용입니다.Scala.js 이벤트 처리

두 이벤트 핸들러는 공통된 코드를 공유하지만 이벤트 핸들러 코딩을 이벤트 핸들러 함수를 반환하는 단일 함수로 최적화하려고하면 올바르게 컴파일되지만 이벤트는 더 이상 갇히지 않습니다. 브라우저.

main 코드의 다음 코드에서 btn.onclick의 이벤트 처리기는 올바르게 작동하지만 cityNameInput.onkeyup의 이벤트 처리기는 더 이상 작동하지 않습니다. 내가 한 일은 이벤트 처리기에 직접 할당 된 코드를 복사하고 Function1[dom.Event, _]을 반환하는 keystrokeHandler이라는 함수에 넣는 것입니다. 이렇게하면 OK가 컴파일되지만 브라우저에서 onkeyup 이벤트가 더 이상 트랩되지 않습니다.

def keystrokeHandler(userInput: String, responseDiv: dom.Element): Function1[dom.Event,_] = 
(e: dom.Event) => { 
    // The city name must be at least 4 characters long 
    if (userInput.length > 3) { 
    responseDiv.innerHTML = "" 

    val xhr = buildXhrRequest(userInput, searchEndpoint) 

    xhr.onload = (e: dom.Event) => { 
     val data: js.Dynamic = js.JSON.parse(xhr.responseText) 

     // Can any cities be found? 
     if (data.count == 0) 
     // Nope, so show error message 
     responseDiv.appendChild(p(s"Cannot find any city names starting with ${userInput}").render) 
     else { 
     // Build a list of weather reports 
     buildSearchList(data, responseDiv) 
     } 
    } 

    // Send XHR request to OpenWeather 
    xhr.send() 
    } 
} 
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
// Main program 
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
@JSExport 
def main(container: dom.html.Div): Unit = { 
    container.innerHTML = "" 

    val cityNameInput = input.render 
    val btn   = button.render 
    val weatherDiv = div.render 

    cityNameInput.defaultValue = owmQueryParams.get("q").get 
    btn.textContent   = "Go" 

    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
    // Button onclick event handler 
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
    btn.onclick = (e: dom.Event) => { 
    if (cityNameInput.value.length > 3) { 
     weatherDiv.innerHTML = "" 

     val xhr = buildXhrRequest(cityNameInput.value, weatherEndpoint) 

     xhr.onload = (e: dom.Event) => { 
     val data = js.JSON.parse(xhr.responseText) 

     // Can the city be found? 
     if (data.cod == "404") 
     // Nope, so show error message 
      weatherDiv.appendChild(p(s"City ${cityNameInput.value} not found").render) 
     else { 
      // So first add the div containing both the weather information 
      // and the empty div that will hold the slippy map. 
      // This is needed because Leaflet writes the map information to an 
      // existing DOM element 
      val report = new WeatherReportBuilder(data) 
      weatherDiv.appendChild(buildWeatherReport(report, 0)) 

      buildSlippyMap("mapDiv0", report) 
     } 
     } 

     // Send XHR request to OpenWeather 
     xhr.send() 
    } 
    } 

    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
    // Input field onkeyup event handler 
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
    cityNameInput.onkeyup = keystrokeHandler(cityNameInput.value, weatherDiv) 

    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
    // Write HTML to the screen 
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
    container.appendChild(
    div(
     h1("Weather Report"), 
     table(
     tr(td("Enter a city name (min 4 characters)"), td(cityNameInput)), 
     tr(td(), td(style := "text-align: right", btn)) 
    ), 
     weatherDiv 
    ).render 
) 
} 

무엇이 문제입니까?

keystrokeHandler 함수가 일부 특수 Scala.Js 이벤트 핸들러 유형을 반환해야합니까? 아니면 다른 것입니까?

감사

크리스 W는

답변

1

나는 문제가 여기에있다 생각 :

가 트리거 이벤트 핸들러하지만 userInput 시간 핸들러에 cityNameInput.value 에 얼어
cityNameInput.onkeyup = keystrokeHandler(cityNameInput.value, weatherDiv) 

cityNameInput.value의 현재 값으로 변경되는 대신이 생성되었습니다. 실제로, 그 선은 분명 cityNameInput.value 한 번만 평가되어 있습니다

val userInput = cityNameInput.value 
cityNameInput.onkeyup = keystrokeHandler(userInput, weatherDiv) 

에 해당합니다. 이 함수 (핸들러)가 호출 될 때마다 평가 될 수 있도록

대신, keystrokeHandler에 매개 변수와 익명 함수 내부에 액세스 cityNameInput.valuecityNameInput 자체를 제공해야합니다.

+0

아, 그게 전부입니다. 감사 –