Bob's Blog

Web开发、测试框架、自动化平台、APP开发、机器学习等

返回上页首页

MAUI加Blazor做一个跨平台的记账APP(七)组件



实际上每个页面都可以是一个组件或者叫子模块。加上了路由和代码逻辑后,使其成为了一个相对独立的页面。

但我们有时候也需要自定义一些可以复用的组件,嵌入到特定的几个页面里,这里记录一下。

比如我现在想在账户总览页面上增加一个小区域,用来展示一旦请求失败或者数据缺失时的错误信息。发现其他页面也会需要这个区域,于是决定把错误提示的区域做成一个可以复用的组件。

首先在pages目录下增加ErrorComponent.razor文件,展示一行大字和一行红色的小字,小字是具体的错误信息,错误信息可以通过传递参数的方式来展示不同的文本,也设置了默认值为'未知错误':

<h3>出错啦</h3>

<span style="color: red;">@ErrorMessage</span>


@code {

    [Parameter]
    public string ErrorMessage { get; set; }

    protected override void OnParametersSet()
    {
        if (string.IsNullOrWhiteSpace(ErrorMessage))
        {
            ErrorMessage = "未知错误";
        }
    }

}

接着直接在其他页面里作为标签一样使用就可以了。和vue之类的差不多,不过更方便一点的是都不需要导入了,直接用。

@page "/accounts"

<PageTitle>账户总览</PageTitle>

<h1>资金账户汇总</h1>

@if (@hasError)
{
    <hr/>
    <ErrorComponent></ErrorComponent>
    <ErrorComponent ErrorMessage="this is a customized error message"></ErrorComponent>
}

这里有一个hasError的字段决定是否展示这个区域,改一点对应的razor.cs文件,设置为true就显示了。当然实际需要根据异常捕获来改这个值和改实际的错误信息。

namespace accountingMAUIBlazor.Pages;

public partial class Accounts
{
	public bool hasError = true;
}

现在要在其他页面里也继续加这个组件,然后就觉得有点麻烦,我一定要在所有需要的页面都添加一次吗?有没有可能在一个统一的地方加了,其他地方就只管传值就行了。

然后试了下,有办法。

我们可以加到MainLayout.razor文件里,这个文件里就是定义统一布局的,在里面我们能看到NavMenu还有Body。打算加在Body之后。

首先我们需要用到<CascadingValue Value="this"> //.... </CascadingValue>,将页面内容包裹起来。 

于是MainLayout.razor的内容就变成了:

@using accountingMAUIBlazor.Pages;
@inherits LayoutComponentBase

<div class="page">
    <CascadingValue Value="this">
        <div class="sidebar">
            <NavMenu />
        </div>

        <main>
            <div class="top-row px-4">
                <a href="https://docs.microsoft.com/aspnet/" target="_blank">About</a>
            </div>

            <article class="content px-4">
                @Body

                @if (@hasErrorGlobal)
                {
                    <hr />
                    <ErrorComponent></ErrorComponent>
                    <ErrorComponent ErrorMessage=@customizedError></ErrorComponent>
                }
            </article>
        </main>
    </CascadingValue>
</div>


@code {
    public string customizedError = "this is a customized error message";
    private bool _hasErrorGlobal;
    public bool hasErrorGlobal
    {
        get => _hasErrorGlobal;
        set
        {
            if (_hasErrorGlobal != value)
            {
                _hasErrorGlobal = value;
                InvokeAsync(() => StateHasChanged());
            }
        }
    }

    protected override void OnParametersSet()
    {
        _hasErrorGlobal = false;
    }
}

这里OnParametersSet会在每一次加载时将hasErrorGlobal给恢复为false,以免一个页面出错,所有的都在提示错误。

接着其他页面就不需要指定这个组件标签了,只需要在页面代码里改一下字段的值就可以了。

accounts.razor里去掉ErrorComponent:

@page "/accounts"

<PageTitle>账户总览</PageTitle>

<h1>资金账户汇总</h1>

accounts.razor.cs里需要通过CascadingParameter来对应到MainLayout,这里还是直接在页面初始化时让其显示错误区域,之后根据异常捕获来更改:

using accountingMAUIBlazor.Shared;
using Microsoft.AspNetCore.Components;

namespace accountingMAUIBlazor.Pages;

public partial class Accounts
{
    [CascadingParameter]
    public MainLayout Layout { get; set; }

    protected override void OnInitialized()
    {
        Layout.hasErrorGlobal = true;
    }
}

效果和上图一样,这样会更简便一点。

下一篇:  Django定时任务
上一篇:  MAUI加Blazor做一个跨平台的记账APP(六)界面美化

共有0条评论

添加评论

暂无评论