【问题标题】:Unable to observe page navigation using F# Async support in Xamarin.Forms无法使用 Xamarin.Forms 中的 F# 异步支持观察页面导航
【发布时间】:2018-10-24 04:42:09
【问题描述】:

我无法观察页面导航。

命令:

member x.AddBankcard =    DelegateCommand( (fun _ -> async { do! navigate() 
                                                           } |> Async.RunSynchronously 
                                                             |> ignore ) ,
                                            fun _ -> true) :> ICommand

发布导航请求:

let navigate() =

    account 
     |> PageRequest.AddBankcard 
     |> broadcastToAsync pageRequesthandlers     

通知订阅者请求:

let broadcastToAsync<'a> (handlers:(list<'a -> Async<unit>>)) (msg:'a) : Async<unit> =

    async { handlers |> List.map (fun handle -> async { do! handle msg }) |> ignore }

手柄导航:

let handle = function
    | PageRequest.AddBankcard _ ->
        page |> function 
        | :? UI.AddBankcard as pageRequest ->
            ...
            async { do! navigationPage.PushAsync(pageRequest) |> Async.AwaitTask }

        | _ -> async { () }
    | _ -> async { () }

注意:

  1. 不发生页面导航。

  2. 我没有收到任何异常。

  3. 我在输出窗口中没有看到任何线索

  4. 我的直觉是我没有正确使用异步。

    异步{做! navigationPage.PushAsync(pageRequest) |> Async.AwaitTask }

更新:

我还尝试了以下方法:

let navigationPage = (app:?>Application).MainPage:?>NavigationPage

let navigate () = async  {
    do! navigationPage.PushAsync(pageRequest) |> awaitTask
}

navigate() |> Async.RunSynchronously |> ignore

Here's the source code

【问题讨论】:

    标签: xamarin.forms f#


    【解决方案1】:

    只有在异步/任务操作完成后必须执行代码时才需要 async {...} 块。

    对于导航,之后通常无需执行任何操作(某些 MVVM 框架除外)。ignore 是必需的,因为函数签名要求返回该单元并且导航方法返回 Task。在 C# 中,Task 在调用时会启动,而在 F# 中 async 块则不会。

    以下代码是一个非常简单的导航示例,不需要async 关键字或Async.AwaitTask 等。

    open Xamarin.Forms
    open Xamarin.Forms.Xaml
    
    type NextPage(app:Application) = 
        inherit ContentPage() 
    
        let button = Button(Text = "Back")
        do 
            button.Clicked.Add (fun _ -> app.MainPage.Navigation.PopAsync () |> ignore )
            base.Content <- nextButton
    
    type MainPage(app:Application) =
        inherit ContentPage()
    
        let nextButton = Button(Text = "Next")
        do 
            nextButton.Clicked.Add (fun _ -> 
                let nextPage = NextPage app
                app.MainPage.Navigation.PushAsync nextPage |> ignore )
    
            base.Content <- nextButton
    
    type App() as this =
        inherit Application()
        do this.MainPage <- NavigationPage(MainPage(this))
    

    【讨论】:

      【解决方案2】:

      我可以告诉你,函数broadcastToAsync 并没有真正执行任何操作:

      let broadcastToAsync<'a> (handlers:(list<'a -> Async<unit>>)) (msg:'a) : Async<unit> =
          async { handlers |> List.map (fun handle -> async { do! handle msg }) |> ignore }
      

      原因是它创建了一个asyncs 列表,然后是ignores 它。

      我建议你把List.map改成List.iter去掉|&gt; ignore并调用Async.RunSynchronously

      let broadcastToAsync handlers msg =
          handlers |> List.iter (fun handle -> handle msg |> Async.RunSynchronously )
      
      "msg" |> broadcastToAsync [ 
              fun msg -> async { printfn "1: %A" msg}
              fun msg -> async { printfn "2: %A" msg} ] 
      
      // 1: "msg"
      // 2: "msg"
      

      【讨论】:

      • 谢谢。但是我仍然遇到异常: async { navigationPage.PushAsync(pageRequest) |> Async.AwaitTask |> Async.RunSynchronously |> ignore }
      • 你收到什么信息?
      • 我的应用现在挂起:navigationPage.PushAsync(pageRequest) |> Async.AwaitIAsyncResult |> Async.Ignore
      【解决方案3】:

      以下代码有效:

      let navigationPage = (app:?>Application).MainPage:?>NavigationPage
      navigationPage.PushAsync(pageRequest) |> Async.AwaitTask |> ignore
      

      下面是一些将页面从堆栈中弹出的代码:

      app |> function
      | :? Application as xForms -> 
      
      let navigationPage = xForms.MainPage:?>NavigationPage
      navigationPage.PopAsync() |> Async.AwaitTask |> ignore
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-09-01
        • 1970-01-01
        相关资源
        最近更新 更多