Elm应用中按钮点击无法触发导航,该如何处理?
嗨,我明白你的困扰了——Element.link能正常触发导航,但Input.button点击却没反应,这是因为两者的工作逻辑不一样:Element.link是Elm专为路由导航设计的组件,内部已经封装了触发LinkClicked消息的逻辑;而Input.button只是一个普通的交互按钮,它的onPress只会发送你指定的自定义消息,不会自动处理导航动作。
要让按钮点击也能实现导航,你只需要在按钮的消息处理中手动调用Elm的导航命令就行,具体步骤如下:
确保你的Model持有导航Key
首先,你的Model需要保存Browser.Navigation.Key,这个Key是初始化Browser.application时获取的,用来执行导航操作。比如:type alias Model = { key : Browser.Navigation.Key -- 这里是你Model里的其他字段 }初始化的时候记得把Key存入Model:
init : () -> Url.Url -> Browser.Navigation.Key -> (Model, Cmd Msg) init flags url key = ( { key = key -- 初始化其他字段 } , Cmd.none )修改按钮的
onPress消息
你可以选择两种方式:要么给按钮发送一个专门的导航消息,要么在现有的StartSearch消息里同时处理业务逻辑和导航。方式一:添加专门的导航消息
先扩展你的Msg类型:type Msg = StartSearch | LinkClicked Browser.UrlRequest | UrlChanged Url.Url | NavigateTo String -- 新增导航消息然后修改按钮:
Input.button [ centerX ] { onPress = Just (NavigateTo "/search") , label = text "Search" }方式二:复用现有的
StartSearch消息
如果你希望点击按钮同时执行StartSearch的业务逻辑和导航,直接保留原来的按钮定义即可:Input.button [ centerX ] { onPress = Just StartSearch , label = text "Search" }在Update函数中处理导航
不管用哪种方式,都需要在update里调用导航命令:如果用方式一(
NavigateTo消息):update : Msg -> Model -> (Model, Cmd Msg) update msg model = case msg of NavigateTo url -> ( model , Browser.Navigation.pushUrl model.key url -- 触发导航,添加历史记录 ) -- 其他消息处理...如果用方式二(
StartSearch消息):update : Msg -> Model -> (Model, Cmd Msg) update msg model = case msg of StartSearch -> ( model , Cmd.batch [ -- 这里可以放StartSearch对应的业务命令 Browser.Navigation.pushUrl model.key "/search" ] ) -- 其他消息处理...如果你不想在浏览器历史中添加新条目,可以用
Browser.Navigation.replaceUrl代替pushUrl。
这样处理后,点击按钮就能像Element.link一样触发页面导航啦!
内容的提问来源于stack exchange,提问作者noamt

