2016-12-15 96 views
12

我正在使用現有的Rails應用程序,導航必須繼續在後端構建(由於複雜性和時間限制)。預期的結果是有一些使用Elm生成的頁面,有些使用Rails,不使用哈希,也不使用整頁重新加載(至少對於Elm頁面)。導航的簡化版本是這樣的:是否有可能在Elm應用程序之外構建的現有導航驅動Elm應用程序?

<nav> 
    <a href="rails-page-1">... 
    <a href="rails-page-2">... 
    <a href="elm-page-1">... 
    <a href="elm-page-2">... 
</nav> 

<div id="elm-container"></div> 

我與榆樹導航包試驗和elm-route-url,可能與後者即將關閉,除非我從根本上誤解了包的能力。

有沒有辦法做到這一點?我已經使用哈希標記工作,但沒有它們就沒有運氣。

+0

我認爲這是可行的事件監聽到你的錨鏈接連接到的preventDefault並通過端口來傳遞的意圖,榆樹 –

+0

@SimonH似乎是這樣,我正在考慮這個選擇。如果可能的話,我想看看如何留在Elm。 – scoots

回答

7

使用哈希標籤

那麼你有一個輕笑了我。

我有這個人在我的Helpers.elm文件中,我可以用它來代替Html.Events.click

{-| Useful for overriding the default `<a>` behavior which 
    causes a refresh, but can be used anywhere 
-} 
overrideClick : a -> Attribute a 
overrideClick = 
    Decode.succeed 
     >> onWithOptions "click" 
      { stopPropagation = False 
      , preventDefault = True 
      } 

所以上a [ overrideClick (NavigateTo "/route"), href "/route" ] [ text "link" ]這將使中單擊元素以及使用按壓狀態更新導航。

您需要的是與pushState一起使用的JavaScript類似的東西,而且您不想毀掉中間點擊體驗。您可以劫持其所有事件中的所有<a> s,preventDefault以停止瀏覽器導航,並通過目標的href推入新狀態。您可以將導航的<a> s委託給事件處理程序。由於Navigation運行時不支持在外部監聽歷史記錄更改(而似乎是使用效果管理器),所以必須將該值通過端口推送 - 幸運的是,如果您使用的是Navigation包,則應該已經有件。

在Elm端,使用UrlParser.parsePathNavigation programs之一結合使用。創建一個端口以訂閱使用與其內部URL更改相同的消息。

import Navigation exposing (Location) 


port externalPush : (Location -> msg) -> Sub msg 


type Msg 
    = UrlChange Location 
    | ... 


main = 
    Navigation.program UrlChange 
     { ... 
     , subscriptions : \_ -> externalPush UrlChange 
     } 

頁面加載後,使用此:

const hijackNavClick = (event) => { 
    // polyfill `matches` if needed 
    if (event.target.matches("a[href]")) { 
    // prevent the browser navigation 
    event.preventDefault() 
    // push the new url 
    window.history.pushState({}, "", event.target.href) 
    // send the new location into the Elm runtime via port 
    // assuming `app` is the name of `Elm.Main.embed` or 
    // whatever 
    app.ports.externalPush.send(window.location) 
    } 
} 


// your nav selector here 
const nav = document.querySelector("nav") 


nav.addEventListener("click", hijackNavClick, false) 
+0

謝謝,我已採納您的建議。使用這種解決方案,是否需要使用標誌或端口來使其完全正常工作?如果沒有,你能否詳細說明榆木會發生什麼?到目前爲止,我的更新沒有被觸發。 – scoots

+0

Arg ...是的,我挖入本機代碼(https://github.com/elm-lang/navigation/blob/2.0.1/src/Native/Navigation.js),它並沒有出現它聽取改變事件。我已經用端口解決方案更新了主要答案。 – toastal

相關問題