8wDlpd.png
8wDFp9.png
8wDEOx.png
8wDMfH.png
8wDKte.png

useQueries 失去了并行查询数据的能力,因为 Next.js 要求服务器组件异步

Abdul Qadeer 3月前

128 0

该应用程序由 Next.js 运行。我有一个 useQueries 钩子:const userQueries = useQueries({ queries: user.contacts.map((contactId: string) => ({ queryKey: ['contact', conta...

该应用程序由 Next.js 运行。

我有一个 useQueries 钩子:

    const userQueries = useQueries({
        queries: user.contacts.map((contactId: string) => ({
            queryKey: ['contact', contactId],
            queryFn: () => getUserById(contactId),
        }))
    });

api.ts 文件中的函数“getUserById”:

export async function getUserById(userId: string) {
    const supabase = createClient();
    let {data} = await supabase
        .from('users')
        .select()
        .eq('id', userId);

    return data && data[0]

}

我发现当我以这种方式加载数据时,它会按顺序加载而不是并行加载。

我尝试将 api 函数设为非异步,以便每个请求不会等待前一个请求,但 Next.js 禁止在没有“async”前缀的情况下执行服务器操作。有办法解决这个问题吗?

帖子版权声明 1、本帖标题:useQueries 失去了并行查询数据的能力,因为 Next.js 要求服务器组件异步
    本站网址:http://xjnalaquan.com/
2、本网站的资源部分来源于网络,如有侵权,请联系站长进行删除处理。
3、会员发帖仅代表会员个人观点,并不代表本站赞同其观点和对其真实性负责。
4、本站一律禁止以任何方式发布或转载任何违法的相关信息,访客发现请向站长举报
5、站长邮箱:yeweds@126.com 除非注明,本帖由Abdul Qadeer在本站《typescript》版块原创发布, 转载请注明出处!
最新回复 (0)
  • 我正在开发一款专用于 Windows 的 MAUI C# 应用程序。这款应用程序的独特之处在于它与本地数据库配合使用,并调用填充服务器上数据库的 API。在此应用程序中,我有一个 p...

    我正在开发一款专用于 Windows 的 MAUI C# 应用程序。这款应用程序的独特之处在于它与本地数据库配合使用,并调用一个 API 来填充服务器上的数据库。在此应用程序中,我有一个显示项目列表的页面。在此页面上,我还有一些按钮,允许我添加/更新/删除此列表中的项目。这些按钮会调出一个用于更新或添加项目的模式。

    当我单击其中一个按钮时,模态框出现,然后我进行更改。由于模态框的背景是透明的,我可以看到修改已应用于列表。但是,模态框不会像代码中预期的那样自动关闭。我必须单击“退出”才能使模态框消失。

    返回列表后,如果我想再次与列表交互,我会单击其中一个按钮。模式打开,我执行操作(添加/更新),我看到修改正在进行,但模式没有关闭并冻结。如果我单击“退出”,我会收到此错误:Application.Current.MainPage.Navigation.ModalStack.Count = 0,并且应用程序崩溃。

    如果我将按钮中的所有逻辑都注释掉,我也会遇到同样的问题。

    我尝试了很多方法,但我觉得我在主线程管理中明显缺少了一些东西。我不太了解 MAUI 中的线程。有人能帮我吗?

    提前致谢。

    这是我的代码,其中我的列表的视图

    <?xml version="1.0" encoding="utf-8" ?>
    <ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
                 xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
                 x:Class="FntrAudit.Views.RequiredDisplayPage"
                 Title="Affichage Obligatoire">
        <Grid RowDefinitions="Auto,*,Auto"
           ColumnDefinitions="*,*,*">
            <Label Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="3" Text="Affichages obligatoires" FontSize="Large"></Label>
    
            <ListView Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="3" ItemsSource="{Binding RequiredDisplays}">
                <ListView.ItemTemplate>
                    <DataTemplate >
                        <ViewCell>
                            <StackLayout Orientation="Horizontal" VerticalOptions="Center" Spacing="10">
                                <CheckBox IsChecked="{Binding IsOk}"  VerticalOptions="Center"/>
                                <Label Text="{Binding Intitule}" VerticalOptions="Center" HorizontalOptions="FillAndExpand" LineBreakMode="WordWrap"/>
                                <ImageButton Clicked="UpdateDoc" HeightRequest="20" WidthRequest="20" Source="update.png" CommandParameter="{Binding .}"></ImageButton>
                                <ImageButton Clicked="Delete_Clicked" HeightRequest="20" WidthRequest="20" Source="delete.png" CommandParameter="{Binding .}"></ImageButton>
                            </StackLayout>
                        </ViewCell>
                    </DataTemplate>
                </ListView.ItemTemplate>
            </ListView>
            <Button   BackgroundColor="#AE1439" Grid.Row="2" Grid.Column="1"  Text="Enregistrer et revenir à l'audit" Margin="5" Clicked="Record_Clicked" HorizontalOptions="Fill"></Button>
            <Button   BackgroundColor="#AE1439" Grid.Row="2" Grid.Column="0"  Text="Ajouter document obligatoire" Margin="5" Clicked="AddDoc" HorizontalOptions="Fill"></Button>
        </Grid>
    </ContentPage>
    

    背后的代码

    using FntrAudit.DALApi;
    using FntrAudit.Data;
    using FntrAudit.Models;
    using FntrAudit.Utils;
    using FntrAudit.Views.Modal;
    using Microsoft.EntityFrameworkCore;
    using System.Collections.ObjectModel;
    
    namespace FntrAudit.Views;
    
    public partial class RequiredDisplayPage : ContentPage
    {
        private Audit _audit;
        SqliteDbContext _db = new SqliteDbContext();
        private ObservableCollection<RequiredDisplay> requiredDisplays;
        private RestService<RequiredDisplay> _requiredDisplayService = new RestService<RequiredDisplay>();
        private RestService<LogFromApp> _LogService = new RestService<LogFromApp>();
        public ObservableCollection<RequiredDisplay> RequiredDisplays
        {
            get { return requiredDisplays; }
            set
            {
                if (requiredDisplays != value)
                {
                    requiredDisplays = value;
                    OnPropertyChanged(nameof(RequiredDisplays));
                }
            }
        }
        public RequiredDisplayPage(Audit audit)
        {
            InitializeComponent();
            _audit = audit;
            InitializeAsync();
        }
        private async void InitializeAsync()
        {
            await LoadRequiredDoc();
        }
    
        public async Task LoadRequiredDoc()
        {
            try
            {
                Console.WriteLine("Loading required documents...");
                bool hasWeb = Connectivity.Current.NetworkAccess == NetworkAccess.Internet;
                List<RequiredDisplay> requiredDisplays = new List<RequiredDisplay>();
    
    
                if (_audit.RequiredDisplay.Any(rd => rd.IsOk))
                {
                    RequiredDisplays = new ObservableCollection<RequiredDisplay>(_audit.RequiredDisplay);
                }
                else
                {
                    RequiredDisplays = new ObservableCollection<RequiredDisplay>(_audit.RequiredDisplay);
    
                }
    
                await Task.Delay(1000);
                this.BindingContext = this;
                Console.WriteLine("Required documents loaded successfully.");
            }
            catch(Exception ex)
            {
                var t = ex.Message;
                Console.WriteLine($"Error loading required documents: {ex.Message}");
            }
          
        }
    
        private async void Delete_Clicked(object sender, EventArgs e)
        {
            try
            {
                bool answer = await DisplayAlert("Supprimer un document obligatoire", "Êtes-vous sûr de vouloir supprimer ce document ?", "Oui", "Non");
    
                if (answer)
                {
                    if (sender is ImageButton button && button.CommandParameter is RequiredDisplay toDelete)
                    {
                        try
                        {
                            Console.WriteLine($"Attempting to delete document: {toDelete.GuidRDisplay}");
                            _db.RequiredDisplay.Remove(toDelete);
                            await _db.SaveChangesAsync();
                            await _requiredDisplayService.DeleteTodoItemAsync(toDelete.GuidRDisplay, Constantes.URLAPI + "RequiredDisplay/");
                            RequiredDisplays.Remove(toDelete);
                            Console.WriteLine($"Document {toDelete.GuidRDisplay} deleted successfully.");
                        }
                        catch (DbUpdateConcurrencyException)
                        {
                            await _db.Entry(toDelete).ReloadAsync();
                            await DisplayAlert("Échec de la suppression", "Le document a été modifié ou supprimé par une autre transaction. Veuillez réessayer.", "OK");
                            Console.WriteLine($"Concurrency error while deleting document: {toDelete.GuidRDisplay}");
                        }
                        catch (Exception ex)
                        {
                            LogFromApp logFromApp = new LogFromApp()
                            {
                                DateCreation = DateTime.Now,
                                Intitule = "ModalRequired delete doc (UserContext ContextCurrent) " + ex.Message,
                                Trace = ex.ToString(),
                                UserInvolved = " "
                            };
    
                            await _LogService.Create(logFromApp, Constantes.URLAPILOG, true);
                            await DisplayAlert("Erreur", "Une erreur est survenue lors de la suppression du document.", "OK");
                            Console.WriteLine($"Error deleting document: {ex.Message}");
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                await DisplayAlert("Erreur", "Une erreur est survenue lors de la suppression du document.", "OK");
                Console.WriteLine("Erreur lors de la suppression du document : " + ex.Message);
            }
        }
    
        //public async void Delete_Clicked(object sender, EventArgs e)
        //{
        //    bool answer = false;
        //    try
        //    {
        //         answer = await DisplayAlert("Supprimer un document obligatoire", "Êtes-vous sûr de vouloir supprimer ce document ?", "Oui", "Non");
        //    }
        //    catch(Exception ex)
        //    {
        //        var toto = ex.Message;
        //    }
    
        //    if (answer)
        //    {
        //        if (sender is ImageButton button && button.CommandParameter is RequiredDisplay toDelete)
        //        {
        //            try
        //            {
        //                _db.RequiredDisplay.Remove(toDelete);
        //                _db.SaveChanges();
        //                await _requiredDisplayService.DeleteTodoItemAsync(toDelete.GuidRDisplay, Constantes.URLAPI + "RequiredDisplay/");
        //                RequiredDisplays.Remove(toDelete);
        //            }
        //            catch (DbUpdateConcurrencyException ex)
        //            {
        //                // Option 1: Raffraîchir l'entité depuis la base de données
        //                await _db.Entry(toDelete).ReloadAsync();
    
        //                // Afficher un message d'erreur à l'utilisateur
        //                await DisplayAlert("Échec de la suppression", "Le document a été modifié ou supprimé par une autre transaction. Veuillez réessayer.", "OK");
    
        //                // Option 2: Tentative de réexécution de la suppression après rechargement
        //                // _db.RequiredDisplay.Remove(toDelete);
        //                // _db.SaveChanges();
        //            }
        //            catch (Exception ex)
        //            {
        //                // Afficher un message d'erreur générique
        //                await DisplayAlert("Erreur", "Une erreur est survenue lors de la suppression du document.", "OK");
        //            }
        //        }
        //    }
        //}
        public async void Record_Clicked(object sender, EventArgs e)
        {
            try
            {
                Console.WriteLine("Recording clicked.");
                _audit.RequiredDisplay = RequiredDisplays.ToList();
                await Application.Current.MainPage.Navigation.PopModalAsync();
                Console.WriteLine("Modal closed successfully.");
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Error in Record_Clicked: {ex.Message}");
            }
        }
        public async void AddDoc(object sender, EventArgs e)
        {
            try
            {
                RequiredDisplay requiredDisplay = new RequiredDisplay();
                var modal = new ModalRequiredDisplay(requiredDisplay, true);
                modal.RequiredDisplays = this.RequiredDisplays;
                //  await Application.Current.MainPage.Navigation.PushModalAsync(modal);
    
                var tcs = new TaskCompletionSource<bool>();
                modal.Disappearing += async (s, args) =>
                {
                    Console.WriteLine("Modal disappearing...");
                    if (!tcs.Task.IsCompleted)
                    {
                        tcs.SetResult(true);
                    }
    
                };
                await Application.Current.MainPage.Navigation.PushModalAsync(modal);
                await tcs.Task;  // Wait for the modal to close
                await LoadRequiredDoc();
            }
            catch(Exception ex)
            {
                Console.WriteLine($"Error in AddDoc: {ex.Message}");
            }
           
           
        }
    
        public async void UpdateDoc(object sender, EventArgs e)
        {
            try
            {
                if (sender is ImageButton button && button.CommandParameter is RequiredDisplay toUpdate)
                {
                    var modal = new ModalRequiredDisplay(toUpdate, false);
                    modal.RequiredDisplays = this.RequiredDisplays;
    
                    var tcs = new TaskCompletionSource<bool>();
                    modal.Disappearing += (s, args) =>
                    {
                        Console.WriteLine("Modal disappearing...");
                        if (!tcs.Task.IsCompleted)
                        {
                            tcs.SetResult(true);
                        }
                    };
    
                    await Application.Current.MainPage.Navigation.PushModalAsync(modal);
                    Console.WriteLine("Modal pushed to stack.");
                    await tcs.Task;  // Wait for the modal to close
                    Console.WriteLine("Modal closed.");
                    await LoadRequiredDoc();
                }
            
            }catch(Exception ex)
            {
                var t = ex.Message;
            }
        }
    }
    

    情态动词

    <?xml version="1.0" encoding="utf-8" ?>
    <ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
                 xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
                 x:Class="FntrAudit.Views.Modal.ModalRequiredDisplay"
                 BackgroundColor="#00000000"
                 Title="Affichage Obligatoire">
        <ContentView HorizontalOptions="Center" VerticalOptions="Center">
            <ScrollView>
                <Frame BackgroundColor="White" CornerRadius="20" Padding="20"
                   HorizontalOptions="Center" VerticalOptions="Center"
                   WidthRequest="700" HeightRequest="600">
               
                <VerticalStackLayout Spacing="15">
                    <Label Text="{Binding TitleModal}" TextColor="Black" FontSize="24" FontAttributes="Bold" HorizontalOptions="Center"></Label>
    
                    <Editor Text="{Binding Intitule}" Placeholder="Intitulé du document" AutoSize="TextChanges"></Editor>
    
                    <VerticalStackLayout Spacing="10">
                        <Label Text="Effectif de l'entreprise concernée (si besoin)" VerticalOptions="CenterAndExpand" FontAttributes="Bold"/>
                        <VerticalStackLayout Spacing="5">
                            <Grid ColumnDefinitions="Auto,*,Auto" RowDefinitions="Auto" Padding="5">
                                <Label Text="Toutes" Grid.Column="0" VerticalOptions="CenterAndExpand" Margin="0,0,10,0"/>
                                <RadioButton x:Name="All" GroupName="Effectif" IsChecked="True" Grid.Column="2" VerticalOptions="CenterAndExpand"/>
                            </Grid>
                            <Grid ColumnDefinitions="Auto,*,Auto" RowDefinitions="Auto" Padding="5">
                                <Label Text="de 1 à 10" Grid.Column="0" VerticalOptions="CenterAndExpand" Margin="0,0,10,0"/>
                                <RadioButton x:Name="Has1SalOrMore" GroupName="Effectif" IsChecked="{Binding Has1SalOrMore}" Grid.Column="2" VerticalOptions="CenterAndExpand"/>
                            </Grid>
                            <Grid ColumnDefinitions="Auto,*,Auto" RowDefinitions="Auto" Padding="5">
                                <Label Text="de 11 à 50" Grid.Column="0" VerticalOptions="CenterAndExpand" Margin="0,0,10,0"/>
                                <RadioButton x:Name="Has11SalOrMore" GroupName="Effectif" IsChecked="{Binding Has11SalOrMore}" Grid.Column="2" VerticalOptions="CenterAndExpand"/>
                            </Grid>
                            <Grid ColumnDefinitions="Auto,*,Auto" RowDefinitions="Auto" Padding="5">
                                <Label Text="de 51 à 300" Grid.Column="0" VerticalOptions="CenterAndExpand" Margin="0,0,10,0"/>
                                <RadioButton x:Name="Has50SalOrMore" GroupName="Effectif" IsChecked="{Binding Has50SalOrMore}" Grid.Column="2" VerticalOptions="CenterAndExpand"/>
                            </Grid>
                            <Grid ColumnDefinitions="Auto,*,Auto" RowDefinitions="Auto" Padding="5">
                                <Label Text="de 301 à 1000" Grid.Column="0" VerticalOptions="CenterAndExpand" Margin="0,0,10,0"/>
                                <RadioButton x:Name="Has300SalOrMore" GroupName="Effectif" IsChecked="{Binding Has300SalOrMore}" Grid.Column="2" VerticalOptions="CenterAndExpand"/>
                            </Grid>
                            <Grid ColumnDefinitions="Auto,*,Auto" RowDefinitions="Auto" Padding="5">
                                <Label Text="1000 et plus" Grid.Column="0" VerticalOptions="CenterAndExpand" Margin="0,0,10,0"/>
                                <RadioButton x:Name="Has1000SalOrMore" GroupName="Effectif" IsChecked="{Binding Has1000SalOrMore}" Grid.Column="2" VerticalOptions="CenterAndExpand"/>
                            </Grid>
                        </VerticalStackLayout>
                    </VerticalStackLayout>
    
                    <HorizontalStackLayout Spacing="10">
                        <Button BackgroundColor="#007AFF" TextColor="White" Text="Enregistrer" Margin="5" Clicked="AddDoc_Clicked" HorizontalOptions="FillAndExpand"></Button>
                        <Button BackgroundColor="#FF3B30" TextColor="White" Text="Quitter" Margin="5" Clicked="Quit_Clicked" HorizontalOptions="FillAndExpand"></Button>
                    </HorizontalStackLayout>
                </VerticalStackLayout>
            </Frame>
            </ScrollView>
        </ContentView>
    </ContentPage>
    

    背后的代码

    using CommunityToolkit.Maui.Alerts;
    using FntrAudit.DALApi;
    using FntrAudit.Data;
    using FntrAudit.Models;
    using FntrAudit.Services;
    using FntrAudit.Utils;
    using Microsoft.EntityFrameworkCore;
    using System.Collections.ObjectModel;
    
    namespace FntrAudit.Views.Modal;
    
    public partial class ModalRequiredDisplay : ContentPage
    {
        private RequiredDisplay _document;
        private bool _isCreation;
        SqliteDbContext _db = new SqliteDbContext();
        private ObservableCollection<RequiredDisplay> requiredDisplays;
        private RestService<RequiredDisplay> _requiredDisplayService = new RestService<RequiredDisplay>();
        private RestService<LogFromApp> _LogService = new RestService<LogFromApp>();
        
        public ObservableCollection<RequiredDisplay> RequiredDisplays
        {
            get { return requiredDisplays; }
            set
            {
                if (requiredDisplays != value)
                {
                    requiredDisplays = value;
                    OnPropertyChanged(nameof(RequiredDisplays));
    
                }
            }
        }
        public ModalRequiredDisplay(RequiredDisplay document, bool isCreation)
        {
            InitializeComponent();
            _document = document;
            _isCreation = isCreation;
            
            _document.TitleModal = _isCreation ? "Ajout d'un document obligatoire" : "Mise à jour d'un document obligatoire";
           
            this.BindingContext = _document;     
        }
    
        private async void Delete_Clicked(object sender, EventArgs e)
        {
            await CloseModalAsync();
        }
    
        private async void Quit_Clicked(object sender, EventArgs e)
        {
            await CloseModalAsync();
        }
    
       
    
        private async Task AddDoc(object sender, EventArgs e)
        {
            bool hasWeb = Connectivity.Current.NetworkAccess == NetworkAccess.Internet;
           
            try
            {
                if (_isCreation)
                {
    
                    RequiredDisplay required = new RequiredDisplay();
                    _document.IsOk = false;
                    _document.AuditId = 1;
                    _document.GuidRDisplay = Guid.NewGuid().ToString();
    
                    await _db.RequiredDisplay.AddAsync(_document);
                    await _db.SaveChangesAsync();
    
                    Func<Task> saveDocument = async () =>
                    {
                        await _requiredDisplayService.Create(_document, Constantes.URLAPI + "RequiredDisplay", true);
                    };
    
                    if (hasWeb)
                    {
                        await saveDocument.Invoke();
                    }
                    else
                    {
                        var connectivityService = new ConnectivityService();
                        connectivityService.AddTask(saveDocument);
                    }
                }
                else
                {
                    _db.Update(_document);
                    await _db.SaveChangesAsync();
    
                    Func<Task> updateDocument = async () =>
                    {
                        await _requiredDisplayService.Create(_document, Constantes.URLAPI + "RequiredDisplay/RequiredDisplay/" + _document.GuidRDisplay, false);
                    };
    
                    if (hasWeb)
                    {
                        await updateDocument.Invoke();
                    }
                    else
                    {
                        var connectivityService = new ConnectivityService();
                        connectivityService.AddTask(updateDocument);
                    }
    
                }
               
                await ShowToasterAsync("Document obligatoire enregistré avec succès.");
            }
            catch (Exception ex)
            {
                LogFromApp logFromApp = new LogFromApp()
                {
                    DateCreation = DateTime.Now,
                    Intitule = "ModalRequired (UserContext ContextCurrent) " + ex.Message,
                    Trace = ex.ToString(),
                    UserInvolved = " "
                };
    
                await _LogService.Create(logFromApp, Constantes.URLAPILOG, true);
            }
            finally
            {
                try
                {
                    if (RequiredDisplays == null)
                    {
                        RequiredDisplays = new ObservableCollection<RequiredDisplay>();
                    }
    
                    RequiredDisplay requiredDisplay = null;
    
                    if (RequiredDisplays.Count > 0 && _document != null)
                    {
                        requiredDisplay = RequiredDisplays.FirstOrDefault(rd => rd.GuidRDisplay == _document.GuidRDisplay);
                    }
    
                    if (requiredDisplay != null)
                    {
                        int index = RequiredDisplays.IndexOf(requiredDisplay);
                        if (index != -1)
                        {
                            RequiredDisplays[index] = _document;
                        }
                    }
    
                    await CloseModalAsync();
                }
                catch (Exception closeEx)
                {
                    Console.WriteLine("Erreur lors de la fermeture de la modal : " + closeEx.Message);
                }
    
            }
        }
    
        private async Task CloseModalAsync()
        {
            try
            {
                if (Application.Current.MainPage.Navigation.ModalStack.Count > 0)
                {
                    await Application.Current.MainPage.Navigation.PopModalAsync();
                    Console.WriteLine("Modal closed successfully.");
                }
                else
                {
                    Console.WriteLine("Modal stack is empty.");
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Error in CloseModalAsync: {ex.Message}");
            }
        }
    
    
        private async void DeleteDoc(object sender, EventArgs e)
        {
            bool answer = await DisplayAlert("Supprimer un document obligatoire", "Êtes-vous sûr de vouloir supprimer ce document ?", "Oui", "Non");
    
            if (answer)
            {
                if (sender is ImageButton button && button.CommandParameter is RequiredDisplay toDelete)
                {
                    try
                    {
                        _db.RequiredDisplay.Remove(toDelete);
                        await _db.SaveChangesAsync();
                        await _requiredDisplayService.DeleteTodoItemAsync(toDelete.GuidRDisplay, Constantes.URLAPI + "RequiredDisplay/");
                        RequiredDisplays.Remove(toDelete);
                    }
                    catch (DbUpdateConcurrencyException ex)
                    {
                        // Option 1: Raffraîchir l'entité depuis la base de données
                        await _db.Entry(toDelete).ReloadAsync();
    
                        // Afficher un message d'erreur à l'utilisateur
                        await DisplayAlert("Échec de la suppression", "Le document a été modifié ou supprimé par une autre transaction. Veuillez réessayer.", "OK");
    
                        // Option 2: Tentative de réexécution de la suppression après rechargement
                        // _db.RequiredDisplay.Remove(toDelete);
                        // _db.SaveChanges();
                    }
                    catch (Exception ex)
                    {
                        LogFromApp logFromApp = new LogFromApp()
                        {
                            DateCreation = DateTime.Now,
                            Intitule = "ModalRequired delete doc (UserContext ContextCurrent) " + ex.Message,
                            Trace = ex.ToString(),
                            UserInvolved = " "
                        };
    
                        await _LogService.Create(logFromApp, Constantes.URLAPILOG, true);
                        // Afficher un message d'erreur générique
                        await DisplayAlert("Erreur", "Une erreur est survenue lors de la suppression du document.", "OK");
                    }
                }
            }
        }
        private async Task ShowToasterAsync(string message)
        {
            var toast = Toast.Make(message);
            await toast.Show();
        }
    
        public async void AddDoc_Clicked(object sender, EventArgs e)
        {
            await AddDoc(sender, e);
        }
       
    }
    
返回
作者最近主题: