本篇,我们来了解下在Blazor中数据是如何共享的,组件之间又该如何传递参数。

关于Blazor组件

在 Blazor 中,从名为“组件”的自包含代码部分生成 UI。每个组件都可以包含 HTML 和 C# 代码的混合。组件是通过使用 Razor 语法编写的,其中的代码是用 @code 指令标记的。其他指令可用于访问变量、绑定到值以及实现其他呈现任务。

编译应用时,HTML 和代码将编译为组件类。组件一般被编写为扩展名为 .razor 的文件。

关于数据共享

Blazor 包含多种在组件之间共享信息的方法。

(1)可使用组件参数或级联参数将值从父组件发送到子组件。

(2)AppState 模式是另一种可用于存储值并从应用程序中的任何组件访问这些值的方法。

使用组件参数共享

在父组件和子组件的此层次结构中,可以使用组件参数在它们之间共享信息。在子组件上定义这些参数,然后在父组件中设置其值。

例如,在Counter组件中,定义了一个IncrementAmount的组件参数:

@page "/counter"

<PageTitle>Counter</PageTitle>

<h1>Counter</h1>

<p role="status">Current count: @currentCount</p>

<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>

@code {
private int currentCount = 0; [Parameter]
public int IncrementAmount { get; set; } = 1; private void IncrementCount()
{
currentCount += IncrementAmount;
}
}

在调用端只需要下面这样既可,由于Counter组件中还设置了默认值为1,因此,如果调用端不传递,则默认为1。

<Counter IncrementAmount="10" />

此外,还可以使用自定义类用作组件参数,例如:

@using EDT.BlazorServer.App.Models

<p>New Topping: @Topping.Name</p>
<p>Ingredients: @Topping.Ingredients</p> @code {
[Parameter]
public PizzaTopping Topping { get; set; }
}

PizzaTopping的定义如下:

public class PizzaTopping
{
public string Name { get; set; }
public string Ingredients { get; set; }
}

调用方的定义如下:

@page "/pizzas-toppings"

<h1>Our Latest Pizzas and Topping</h1>

<PizzaTopping Topping="@(new PizzaTopping() { Name = "Chilli Sauce", Ingredients = "Three kinds of chilli." })" />

使用级联参数共享

当具有包含子组件的子组件的较深层次结构时,事情便会变得难以应付。组件参数不会从上级组件或沿着层次结构向下自动传递到下级组件。为了完美处理此问题,Blazor 包含了级联参数。在组件中设置级联参数的值时,其值将自动提供给所有子组件。

在父组件中,使用  标记指定将级联到所有子组件的信息。此标记作为内置的 Blazor 组件实现。在该标记内呈现的任何组件都将能够访问该值。

例如,我们有三个组件,其中,CascComp2组件被嵌套在CascComp1组件中,而CascComp1组件又被嵌套在CascCompSamle组件中。他们的调用关系如下:

使用CascadingParameter级联传递参数NickName:

(1)CascCompSample.razor

<!--this is CascCompSample.razor-->

@page "/cascparamsample"

<h3>This is the sample page</h3>

<CascadingValue Value="NickName">
<CascComp1></CascComp1>
</CascadingValue> @code
{
private string NickName = "Edison Zhou";
}

(2)CascComp1.razor

<!--this is CascComp1.razor-->

<h3>Comp1: @NickName</h3>

<CascComp2></CascComp2>

@code {
[CascadingParameter]
public string NickName { get; set; }
}

(3)CascComp2.razor

<!--this is CascComp2.razor-->

<h3>Comp2: @NickName</h3>

@code {
[CascadingParameter]
public string NickName { get; set; }
}

要点:

(1)首先在CascCompSample.razor页面,我们通过把CascComp1嵌套到CascadingValue里面来传递参数。

(2)其次在CascComp1和 CascComp2,不再需要显式传递参数,只需要声明CascadingParameter即可拿到值。

效果:

如果需要级联传递多个参数,可以使用CascadingValue的嵌套,这里我们修改一下CascCompSample.razor组件,让它可以共享两个参数:

<!--this is CascCompSample.razor-->

@page "/cascparamsample"

<h3>This is the sample page</h3>

<CascadingValue Value="currentNickName" Name="NickName">
<CascadingValue Value="currentAge" Name="Age">
<CascComp1></CascComp1>
</CascadingValue>
</CascadingValue> @code
{
private string currentNickName = "Edison Zhou";
private int currentAge = 34;
}

修改CascComp1.razor,增加一个CascadingParameter属性Age:

<!--this is CascComp1.razor-->

<h3>Comp1: @NickName - @Age</h3>

<CascComp2></CascComp2>

@code {
[CascadingParameter(Name="NickName")]
public string NickName { get; set; } [CascadingParameter(Name="Age")]
public int Age { get; set; }
}

CascComp2.razor修改同上,不再赘述。

这里需要注意的是:级联值由父级中的 Name 属性标识,与 [CascadingParameter] 属性中的 Name 值匹配。对于只有一个该类型的参数而言,在子组件中CascadingParameter特性中无需指定Name。但对于如果有多个相同类型的级联参数而言,最好加上Name名称进行指定,以避免找不到。因此,这里也推荐在CascadingValue中指定Name,然后再CascadingParameter特性中指定Name。

最终效果:

使用AppState模式共享

在不同组件之间共享信息的另一种方法是使用 AppState 模式。

即创建一个定义要存储的属性的类,并将其注册为作用域服务。在要设置或使用 AppState 值的任何组件中,注入该服务,然后可以访问其属性。不同于组件参数和级联参数,AppState 中的值可用于应用程序中的所有组件,即使这些组件不是存储该值的组件的子组件也是如此。

例如,创建一个包含销售状态的类:

public class PizzaSalesState
{
public int PizzasSoldToday { get; set; }
}

然后,将该类注入到DI容器中:

builder.Services.AddScoped<PizzaSalesState>();

最后,在任意组件中通过依赖注入来访问该属性:

@page "/"
@using EDT.BlazorServer.App.Models
@inject PizzaSalesState salesState; <PageTitle>Index</PageTitle> <h1>Hello, world!</h1> Welcome to your new app. <SurveyPrompt Title="Your Pizza Shop" /> @*<Counter IncrementAmount="10" />*@
<p>Today, we've sold this many pizzas: @salesState.PizzasSoldToday</p>
<button @onclick="IncrementSales">Buy a Pizza</button> @code {
private void IncrementSales()
{
salesState.PizzasSoldToday++;
}
}

在本例中,由于我们已将计数器的值存储在 AppState 范围内服务中,因此计数会在页面加载期间一直存在,并且对其他用户可见。

最终效果:

小结

本篇,我们了解了数据如何在Blazor中共享。

下一篇,我们学习一下在Blazor中数据绑定的各种花样。

参考资料

Microsoft Docs,《在Blazor应用程序中共享数据》

65号腕,《Blazor中的参数和级联参数》

作者:周旭龙

出处:https://edisonchou.cnblogs.com

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接。

Blazor学习之旅(4)数据共享的更多相关文章

  1. WCF学习之旅—第三个示例之四(三十)

           上接WCF学习之旅—第三个示例之一(二十七)               WCF学习之旅—第三个示例之二(二十八)              WCF学习之旅—第三个示例之三(二十九)   ...

  2. Hadoop学习之旅二:HDFS

    本文基于Hadoop1.X 概述 分布式文件系统主要用来解决如下几个问题: 读写大文件 加速运算 对于某些体积巨大的文件,比如其大小超过了计算机文件系统所能存放的最大限制或者是其大小甚至超过了计算机整 ...

  3. WCF学习之旅—第三个示例之二(二十八)

    上接WCF学习之旅—第三个示例之一(二十七) 五.在项目BookMgr.Model创建实体类数据 第一步,安装Entity Framework 1)  使用NuGet下载最新版的Entity Fram ...

  4. WCF学习之旅—第三个示例之三(二十九)

    上接WCF学习之旅—第三个示例之一(二十七) WCF学习之旅—第三个示例之二(二十八) 在上一篇文章中我们创建了实体对象与接口协定,在这一篇文章中我们来学习如何创建WCF的服务端代码.具体步骤见下面. ...

  5. WCF学习之旅—WCF服务部署到IIS7.5(九)

    上接   WCF学习之旅—WCF寄宿前的准备(八) 四.WCF服务部署到IIS7.5 我们把WCF寄宿在IIS之上,在IIS中宿主一个服务的主要优点是在发生客户端请求时宿主进程会被自动启动,并且你可以 ...

  6. WCF学习之旅—WCF服务部署到应用程序(十)

    上接  WCF学习之旅—WCF寄宿前的准备(八) WCF学习之旅—WCF服务部署到IIS7.5(九) 五.控制台应用程序宿主 (1) 在解决方案下新建控制台输出项目 ConsoleHosting.如下 ...

  7. WCF学习之旅—WCF服务的Windows 服务程序寄宿(十一)

    上接    WCF学习之旅—WCF服务部署到IIS7.5(九) WCF学习之旅—WCF服务部署到应用程序(十) 七 WCF服务的Windows 服务程序寄宿 这种方式的服务寄宿,和IIS一样有一个一样 ...

  8. WCF学习之旅—WCF服务的WAS寄宿(十二)

    上接    WCF学习之旅—WCF服务部署到IIS7.5(九) WCF学习之旅—WCF服务部署到应用程序(十) WCF学习之旅—WCF服务的Windows 服务程序寄宿(十一) 八.WAS宿主 IIS ...

  9. WCF学习之旅—WCF服务的批量寄宿(十三)

    上接    WCF学习之旅—WCF服务部署到IIS7.5(九) WCF学习之旅—WCF服务部署到应用程序(十) WCF学习之旅—WCF服务的Windows 服务程序寄宿(十一) WCF学习之旅—WCF ...

  10. WCF学习之旅—第三个示例之五(三十一)

       上接WCF学习之旅—第三个示例之一(二十七)               WCF学习之旅—第三个示例之二(二十八)              WCF学习之旅—第三个示例之三(二十九) WCF学习 ...

随机推荐

  1. 【Git】Git GUI的使用

    在Git命令行一文中已经对Git的操作命令进行了简单的介绍,但是理论知识过于枯燥,使得初学者在Git的使用上还是会有很大的困难.虽然我更推荐使用Git Bash方式对Git进行操作,但是对于大部分只是 ...

  2. leetcode每日一题:对角线上不同值的数量差

    题目 2711. 对角线上不同值的数量差 给你一个下标从 0 开始.大小为 m x n 的二维矩阵 grid ,请你求解大小同样为 m x n 的答案矩阵 answer . 矩阵 answer 中每个 ...

  3. word突然无法转换latex公式的解决尝试

    正常情况下我在word插入复制的latex公式步骤如下(以\(\mu\neq 10\)为例): 把\(\mu\neq 10\)粘贴到word文档中,选中\(\mu\neq 10\)并同时按下alt和等 ...

  4. unigui的部署【9】

    1.UniGUIServerModule的事件: procedure TUniServerModule.UniGUIServerModuleBeforeInit(Sender: TObject);be ...

  5. FastAPI依赖注入作用域与生命周期控制

    title: FastAPI依赖注入作用域与生命周期控制 date: 2025/04/08 00:02:10 updated: 2025/04/08 00:02:10 author: cmdragon ...

  6. 使用python批量爬取wallhaven.cc壁纸站壁纸

    偶然发现https://wallhaven.cc/这个壁纸站的壁纸还不错,尤其是更新比较频繁,用python写个脚本爬取 点latest,按照更新先后排序,获得新地址,发现地址是分页展示的,每一页24 ...

  7. kettle介绍-Step之加密及解密

    加密 进入kettle的安装目录 cd /d D:\Application\pdi-ce-6.0.0.0-353\data-integration windows系统命令行执行:Encr.bat -k ...

  8. 解决React Warning: Function components cannot be given refs. Attempts to access this ref will fail. Did you mean to use React.forwardRef()?

    问题 当我使用如下方式调用组件子组件UploadModal并且绑定Ref时React报错"Warning: Function components cannot be given refs. ...

  9. 代码随想录第二十四天 | Leecode 93. 复原IP地址 、78. 子集、 90.子集II

    Leecode 93. 复原IP地址 题目描述 有效 IP 地址 正好由四个整数(每个整数位于 0 到 255 之间组成,且不能含有前导 0),整数之间用 '.' 分隔. 例如:"0.1.2 ...

  10. 【经验】VMware|Ubuntu虚拟机连不上网的解决办法(网络重启大法+NAT模式注意开启服务)

    我的版本:Ubuntu20.04.04,iso是清华镜像站的release版本. 问题:NAT模式没有网络连接图标,或者图标闪一下就消失不见,并且无法获取IP地址:但是桥接模式的网络服务却是正常的. ...