मैं purescript-routing
लाइब्रेरी का उपयोग करके, PureScript में पुशस्टेट रूटिंग करने का प्रयास कर रहा हूं। इसे हल करने में मदद करने के लिए, मैंने निम्नलिखित न्यूनतम उदाहरण बनाया है:
module Main where
import Prelude
import Data.Foldable (oneOf)
import Data.Generic.Rep (class Generic)
import Data.Generic.Rep.Show (genericShow)
import Effect (Effect)
import Effect.Console (log)
import Flame (Html, QuerySelector(..))
import Flame.Application.NoEffects as FAN
import Flame.HTML.Attribute as HA
import Flame.HTML.Element as HE
import Routing.Match (Match, end, int, lit, root)
import Routing.PushState (makeInterface, matches)
import Signal.Channel (send)
type Model = {
route :: Route
}
data Message = ChangeRoute Route
data Route
= RouteOne
| RouteTwo
| RouteThree Int
| Root
derive instance genericRoute :: Generic Route _
instance showRoute :: Show Route where
show = genericShow
route :: Match Route
route = root *> oneOf
[ Root <$ end
, RouteOne <$ lit "route-1" <* end
, RouteTwo <$ lit "route-2" <* end
, RouteThree <$> (lit "route-3" *> int)
]
init :: Model
init = { route: Root }
update :: Model -> Message -> Model
update model = case _ of
ChangeRoute x -> model { route = x }
view :: Model -> Html Message
view model = HE.main "main" $
[ HE.p_ ("Route: " <> show model.route)
, HE.ul_
[ HE.li_
[ HE.a [ HA.href "/route-1" ] "route 1"
]
, HE.li_
[ HE.a [ HA.href "/route-2" ] "route 2"
]
, HE.li_
[ HE.a [ HA.href "/route-3/123" ] "route 3"
]
]
]
main :: Effect Unit
main = do
nav <- makeInterface
flameChannel <- FAN.mount (QuerySelector "main")
{ init
, update
, view
}
void $ nav # matches route \oldRoute newRoute -> do
log $ show oldRoute <> " -> " <> show newRoute
send flameChannel [ ChangeRoute newRoute ]
क्या काम करता है:
- रूट पार्सिंग
- कंसोल में वर्तमान मार्ग को प्रिंट करना
क्या काम नहीं करता है: डीओएम में एक लिंक पर क्लिक करने से एप्लिकेशन को सिग्नल भेजे जाने के बजाय पेज लोड द्वारा नियंत्रित किया जाता है।
ब्राउज़र पेज लोड के विपरीत, फ्लेम को भेजे जाने वाले सिग्नल में एक लिंक परिणाम पर क्लिक करने के लिए कौन से कोड परिवर्तन/जोड़ने की आवश्यकता है? क्या मेरा सामान्य दृष्टिकोण भी सही है?
मैंने purescript-routing documentation का उपयोग करने का प्रयास किया है। और प्योरस्क्रिप्ट-रूटिंग टेस्ट समझ हासिल करने के लिए, लेकिन न तो एक पूरा उदाहरण दिखाएं (क्लिक करने योग्य URL सहित)। मैंने RoutingPushHalogenClassic PureScript कुकबुक कोड से भी काम करने की कोशिश की है, लेकिन यह फ्लेम पर लागू नहीं लगता।
1 उत्तर
इसे पूरा करने का यह एक तरीका है:
module Main where
import Prelude
import Data.Foldable (oneOf)
import Data.Generic.Rep (class Generic)
import Data.Generic.Rep.Show (genericShow)
import Data.Maybe (Maybe(..), isNothing)
import Debug.Trace (spy)
import Effect (Effect)
import Effect.Console (log)
import Flame (Html, QuerySelector(..))
import Flame.Application.NoEffects as FAN
import Flame.HTML.Attribute as HA
import Flame.HTML.Element as HE
import Foreign (unsafeToForeign)
import Routing.Match (Match, end, int, lit, root)
import Routing.PushState (PushStateInterface, makeInterface, matches)
import Signal.Channel (Channel, send)
import Web.Event.Event (preventDefault)
type Model
= { navInterface :: PushStateInterface
, route :: Route
}
data Message
= ChangeRouteInternal Route
| ChangeRouteExternal Route
data Route
= RouteOne
| RouteTwo
| RouteThree Int
| Root
derive instance genericRoute :: Generic Route _
instance showRoute :: Show Route where
show = genericShow
route :: Match Route
route =
root
*> oneOf
[ Root <$ end
, RouteOne <$ lit "route-1" <* end
, RouteTwo <$ lit "route-2" <* end
, RouteThree <$> (lit "route-3" *> int) <* end
]
init :: PushStateInterface -> Model
init nav = { navInterface: nav, route: Root }
update :: Model -> Message -> Model
update model = case _ of
ChangeRouteInternal x -> spy "ChangeRouteInternal" model { route = x }
ChangeRouteExternal x -> spy "ChangeRouteExternal" model { route = x }
view :: Model -> Html Message
view model =
HE.main "main"
$ [ HE.p_ ("Route: " <> show model.route)
, HE.ul_
[ HE.li_
[ HE.a (routeAnchorAttributes (ChangeRouteInternal RouteOne)) "route 1"
]
, HE.li_
[ HE.a (routeAnchorAttributes (ChangeRouteInternal RouteTwo)) "route 2"
]
, HE.li_
[ HE.a (routeAnchorAttributes (ChangeRouteInternal (RouteThree 123))) "route 3"
]
]
]
where
routeAnchorAttributes = case _ of
ChangeRouteInternal anchorRoute -> [ HA.href (routeToUrl anchorRoute), onClick_ anchorRoute ]
_ -> []
-- Based on keypress example at:
-- https://github.com/easafe/purescript-flame/blob/master/test/Basic/EffectList.purs
onClick_ clickedRoute =
HA.createRawEvent "click"
$ \event -> do
preventDefault event
model.navInterface.pushState (unsafeToForeign {}) (routeToUrl clickedRoute)
pure $ Just (ChangeRouteInternal clickedRoute)
routeToUrl :: Route -> String
routeToUrl = case _ of
Root -> "/"
RouteOne -> "/route-1"
RouteTwo -> "/route-2"
RouteThree n -> "/route-3/" <> (show n)
routeMatch :: Match Route -> Channel (Array Message) -> PushStateInterface -> Effect Unit
routeMatch m chan =
void
<$> matches m \oldRoute newRoute -> do
log $ show oldRoute <> " -> " <> show newRoute
if isNothing oldRoute then
send chan [ ChangeRouteExternal newRoute ]
else
pure unit
main :: Effect Unit
main = do
nav <- makeInterface
flameChannel <-
FAN.mount (QuerySelector "main")
{ init: init nav
, update
, view
}
routeMatch route flameChannel nav
- इस कोड में अलग-अलग
Message
एप्लिकेशन के अंदर से बाहर होने वाले रूट परिवर्तन के लिए ठोस प्रकार हैं, यानी एड्रेस बार में टाइप करने वाले उपयोगकर्ता से, बाहरी लिंक से एप्लिकेशन लोड करना आदि। यह आवश्यक नहीं है, लेकिन मैं चाहता था यह उजागर करने के लिए कि इन परिस्थितियों के लिए तर्क और कोड पथ भिन्न हैं। routeMatch
बाहरी रूटिंग परिवर्तनों को संभालता है,onClick_
आंतरिक के लिए है और फ्लेम के अपनेcreateRawEvent
फ़ंक्शन।- जबकि फ्लेम डॉक्स क्लिक हैंडलिंग और
preventDefault
को कवर नहीं करता, मुझे की कैप्चर का यह परीक्षणonClick_
बनाते समय बहुत मददगार होता है। - संदेश और आंतरिक स्थिति में परिवर्तन देखने के लिए डेवलपर टूल कंसोल खोलें।