Невозможно наблюдать навигацию по страницам, используя поддержку F # Async в Xamarin.Forms - PullRequest
0 голосов
/ 24 октября 2018

Я не могу наблюдать за навигацией по страницам.

Команда:

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. Мои догадкия не правильно использую 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

Вот исходный код

Ответы [ 3 ]

0 голосов
/ 25 октября 2018

Работает следующий код:

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
0 голосов
/ 25 октября 2018

Блок async {...} необходим только в том случае, если код должен выполняться после завершения операции асинхронизации / задачи.

Для навигации, как правило, после этого ничего делать не нужно (исключение составляют некоторые фреймворки MVVM). ignore требуется, поскольку сигнатура функции требует, чтобы модуль возвращался, а методы навигации возвращали Task,В C # Task запускается при вызове, в то время как async блоки в F # - нет.

Следующий код является очень простым примером навигации без необходимости использования ключевого слова 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))
0 голосов
/ 24 октября 2018

Я могу вам сказать, что функция 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 s.

Я предлагаю вам изменить 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"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...