我无法观察页面导航。
命令:
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 { () }
注意:
不发生页面导航。
我没有收到任何例外。
我在输出窗口中看不到任何线索
我的预感是我没有正确使用异步。
async { do! navigationPage.PushAsync(pageRequest( |> Async.AwaitTask }
更新:
我还尝试了以下方法:
let navigationPage = (app:?>Application).MainPage:?>NavigationPage
let navigate () = async {
do! navigationPage.PushAsync(pageRequest) |> awaitTask
}
navigate() |> Async.RunSynchronously |> ignore
这是源代码
仅当代码必须在异步/任务操作完成后执行时,才需要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))
我可以告诉你,函数broadcastToAsync
并没有真正执行任何操作:
let broadcastToAsync<'a> (handlers:(list<'a -> Async<unit>>)) (msg:'a) : Async<unit> =
async { handlers |> List.map (fun handle -> async { do! handle msg }) |> ignore }
原因是它创建了一个async
列表,然后ignore
它。
我建议您将List.map
更改为List.iter
删除|> 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"
以下代码有效:
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