如何在页面重新加载时正确从在线API获取数据?

问题描述 投票:0回答:1

我正在构建一个 MAUI 应用程序,并试图找出在打开/重新打开 XAML 页面时从互联网获取数据的正确且推荐的方法。

我找到了使用代码隐藏方法的建议:

protected override void OnAppearing()
{
    base.OnAppearing();
    // Code to execute when the page appears
}

protected override void OnDisappearing()
{
    base.OnDisappearing();
    // Code to execute when the page disappears
}

...但我想在我的页面的 ViewModel 中执行此操作。什么才是正确的做法?

c# xaml mvvm maui viewmodel
1个回答
0
投票

您可以尝试通过为您的应用创建

BaseViewModel
BasePage
来实现此目的。

请按照以下步骤操作:

1.安装nuget CommunityToolkit.MVVM

2.创建类

BasePage
如下:

public class BasePage : ContentPage
    {
        public BasePage()
        {
            NavigationPage.SetBackButtonTitle(this, "Back");

            Loaded += OnLoaded;
            Unloaded += OnUnloaded;
        }

        void OnLoaded(object sender, EventArgs e)
        {
            SetupBinding(BindingContext);
        }

        void OnUnloaded(object sender, EventArgs e)
        {
            TearDownBinding(BindingContext);
        }

        protected void SetupBinding(object bindingContext)
        {
            if (bindingContext is BaseViewModel vm)
            {
                vm.DoDisplayAlert += OnDisplayAlert;
                vm.DoNavigate += OnNavigate;
                vm.OnAppearing();
            }
        }

        protected void TearDownBinding(object bindingContext)
        {
            if (bindingContext is BaseViewModel vm)
            {
                vm.OnDisappearing();
                vm.DoDisplayAlert -= OnDisplayAlert;
                vm.DoNavigate -= OnNavigate;
            }
        }

        Task OnDisplayAlert(string message)
        {
            return DisplayAlert(Title, message, "OK");
        }

        Task OnNavigate(BaseViewModel vm, bool showModal)
        {
            var name = vm.GetType().Name;
            name = name.Replace("ViewModel", "Page", StringComparison.Ordinal);

            var ns = GetType().Namespace;
            var pageType = Type.GetType($"{ns}.{name}");

            var page = (BasePage)Activator.CreateInstance(pageType);
            page.BindingContext = vm;

            return showModal
                ? Navigation.PushModalAsync(page)
                : Navigation.PushAsync(page);
        }
    }

3.创建

BaseViewModel.cs
,如下:

 public class BaseViewModel: ObservableObject
    {
/*        bool isBusy;

        public bool IsBusy
        {
            get => isBusy;
            set => SetProperty(ref isBusy, value, onChanged: () => OnPropertyChanged(nameof(IsNotBusy)));
        }*/

        public virtual void OnAppearing()
        {
        }

        public virtual void OnDisappearing()
        {
        }

        internal event Func<string, Task> DoDisplayAlert;

        internal event Func<BaseViewModel, bool, Task> DoNavigate;

        public Task DisplayAlertAsync(string message)
        {
            return DoDisplayAlert?.Invoke(message) ?? Task.CompletedTask;
        }

        public Task NavigateAsync(BaseViewModel vm, bool showModal = false)
        {
            return DoNavigate?.Invoke(vm, showModal) ?? Task.CompletedTask;
        }
    }

3.创建

TestViewModel.cs

public class TestViewModel:BaseViewModel
{
    public override void OnAppearing()
    {
        System.Diagnostics.Debug.WriteLine("-------do something when the page appears");

        base.OnAppearing();
    }


    public override void OnDisappearing()
    {
        System.Diagnostics.Debug.WriteLine("-------do something when the page disappears");

        base.OnDisappearing();
    }
}

4.创建一个扩展

TestPage.xaml
BasePage
并将此页面的
BindingContext
设置为
TestViewModel.cs

<?xml version="1.0" encoding="utf-8" ?>
<views:BasePage
             xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:views="clr-namespace:MauiApp129.Pages"
             xmlns:viewmodels="clr-namespace:MauiApp129.ViewModels"
             Title="TestPage"
             x:Class="MauiApp129.Pages.TestPage"
             >

    <views:BasePage.BindingContext>
        <viewmodels:TestViewModel></viewmodels:TestViewModel>
    </views:BasePage.BindingContext>
    <VerticalStackLayout>
        <Label
            Text="Welcome to .NET MAUI!"
            VerticalOptions="Center"
            HorizontalOptions="Center" />
    </VerticalStackLayout>
</views:BasePage>

TestPage.xaml.cs

public partial class TestPage : BasePage
{
      public TestPage()
      {
            InitializeComponent();
      }

}

5.如果您想导航到

TestPage
,您可以使用以下代码:

    private async void Button_Clicked(object sender, EventArgs e)
    {
        await Navigation.PushAsync((Page)Activator.CreateInstance(typeof(TestPage)));

    }

注:

您也可以参考官方示例:.NET MAUI - 平台集成,其中也使用了

BasePage
BaseViewModel
这种方式。

© www.soinside.com 2019 - 2024. All rights reserved.