翻译自:Study Blazor .NET,转载请注明。

数据绑定

单向绑定

在blazor中单向绑定简单而直接,无需UI刷新或渲染。下面示例展示了单向数据绑定:

//Counter.razor
@page "/counter" <h1>Counter</h1>
<p>Current count: @currentCount</p>
<button class="btn btn-primary" onclick="@IncrementCount">Click me</button> @functions {
int currentCount = 0;
void IncrementCount()
{
currentCount++;
}
}

这里 @currentComponent 的值会根据点击 Click me 按钮的次数而增加。<p> 标签元素的值会自动刷新无需任何其它组件刷新。

双向绑定

Blazor为双向绑定提供多种选择,与一些流行的JS语言相比实现起来更加优雅。

相同组件中使用绑定

在blazor中,bind 特性支持双向数据绑定,在下面的例子中,checkbox 在同一个组件中使用了 bind 属性:

//TwoWayBind.razor
@page "/two-way-binding" <input type="checkbox"
bind="@updateString" />
<p>This string will get value from above text field : @updateString.ToString()</p> @functions {
Boolean updateString {get; set;} = true;
}

双向数据绑定也能用lamda表达式通过 onchange 特性实现。不用担心,Blazor提供了绑定属性的简单方法,更多细节如下:

//TwoWayBind.razor
@page "/two-way-binding" <input type="text"
value="@updateString"
onchange="@((UIChangeEventArgs __e) => updateString = __e.Value.ToString())"/> <p>This string will get value from above text field: @updateString</p> @functions {
string updateString = "";
}

bind 特性可以使用值和事件 bind-value-<onwevent> 进行扩展,上面的示例可以用 oninput 代替 onchange 重写如下:

//TwoWayBind.razor
@page "/two-way-binding" <input type="text"
bind-value-oninput="@updateString" />
<p>This string will get value from above text field : @updateString</p> @functions {
string updateString = "";
}

不同组件间使用绑定

方法 1

组件之间传递的数据通过组件属性及其属性映射完成,这种方法使用 Action<titem> 数据类型。

//ParentComponent.razor
<h3> Parent Component</h3>
<p>String in Parent: @parentString</p>
<button onclick="@PassToChild">Pass String To Child</button> <ChildComponent
ToChild=@parentString
FromChild=@ReceivedFromChild>
</ChildComponent> @functions{
private string parentString = "Initial Parent String";
private void PassToChild()
{
parentString += "- To Child";
}
private void ReceivedFromChild(string str)
{
parentString = str;
StateHasChanged();
}
}
//ChildComponent.razor
<h4>Child Component</h4>
<button onclick="@PassToParent">Pass String to Parent</button>
<p>String received from Parent : @ToChild</p> @functions{
[Parameter]
private string ToChild{get;set;}
[Parameter]
Action<string> FromChild{get;set;} private string childString; private void PassToParent()
{
childString = ToChild + "- To Parent";
FromChild(childString);
}
}

ChildComponent中的 FromChild 特性/属性用 Action<string> 类型从子组件向父组件传递值。在父组件中有一个带有 string 类型参数的响应函数,ChildComponent组件中的按钮点击操作触发这个函数,并且反过来通知 PassToParent 函数,为了通知父组件中的状态已经改变,我们使用了Blazor内置函数 StateHasChanged()

方法 2

这种方法使用 EventCallback 数据类型指定事件变更来传递信息从而代替具体的数据,这里不需要再调用 StateHasChanged() 函数。

//ParentComponent.razor
<h3> Parent Component</h3>
<p>Logging Event triggered from Child: @logString</p> <ChildComponent
Trigger=@TriggerFromChild>
</ChildComponent> @functions{
private string logString = "";
private void TriggerFromChild(UIMouseEventArgs e)
{
logString = e.ToString();
}
}
//ChildComponent.razor
<h4>Child Component</h4>
<button onclick="@Trigger">Trigger Parent</button> @functions{
[Parameter]
private EventCallback<UIMouseEventArgs> Trigger { get; set; }
}

在ChildComponent中,Trigger 属性回调ParentComponent中相应的带有 UIMouseEventArgs参数的TriggerFromChild 方法,同时在父组件中以字符串形式记录。

下面是支持的事件参数:

  • UIEventArgs
  • UIChangeEventArgs
  • UIKeyboardEventArgs
  • UIMouseEventArgs

方法 3

这里是组件间双向绑定的另一种方法,我们可以基于任何事件/方法的执行手动触发一个 Action

//ParentComponent.razor
<h3> Parent Component</h3>
<p>Logging Event triggered from Child: @logString</p> <ChildComponent
EventFromChild=@TriggerFromChild>
</ChildComponent> @functions{
private string logString = "";
private void TriggerFromChild()
{
logString = "Triggered From Child using Action and Invoke";
StateHasChanged();
}
}
//ChildComponent.razor
<h4>Child Component</h4>
<button onclick="@Trigger">Trigger Parent</button> @functions{
[Parameter]
private Action EventFromChild{get;set;} private void Trigger()
{
EventFromChild?.Invoke();
}
}

在ChildComponent中,用内置函数 Invoke 手动触发 EventFromChild Action 属性,同时回调父组件中相应的 TriggerFromChild 方法,在父组件中,通过 StateHasChanged() 通知状态已经改变。

级联值和参数

Blazor提供了一种跨越整个RenderTree(所有组件)传递数据的方法,使用 CascadingValueCascadingParameter 代替传递组件特性。传递的值可以被RenderTree (子组件)通过装饰属性 CascadingParameter 代替 Parameter 接收。

//RootComponent.razor
@page "/base-component"
<h3> App Base Component</h3> <CascadingValue Value="@pName" Name="ProfileName">
<CascadingValue Value="@pAge" Name="ProfileAge">
<ParentComponent/>
</CascadingValue>
</CascadingValue> @functions {
private string pName {get;set;} = "New To Blazor";
private int pAge {get;set;} = 35;
}
//ParentComponent.razor
<h3> Parent Component</h3>
<p> Profile Name is : @Name and Age is : @Age.ToString(); </p> @functions{
[CascadingParameter(Name = "ProfileName")]
string Name { get; set; }
[CascadingParameter(Name = "ProfileAge")]
int Age {get;set;}
}

CascadingParameter 中,Name 参数必须与具有 CascadingValue 组件的 Name 属性匹配,如果我们没有声明 Name,那么 CascadingParameter 中的变量类型与 CascadingValue 中的 Value 属性匹配。

最好声明 Name 参数,以避免混淆,这在应用程序规模增长时很有用。

渲染片段,动态内容

除了用特性从父组件向子组件传递内容,还可以在组件的 tag 元素中传递内容,并且可以使用 RenderFragment 属性在子组件中呈现。

方式 1

ChildContent 是我们需要在子组件中使用的命名约定,以获取父组件的内容,

//ParentComponent.razor
<h3> Parent Component</h3>
<ChildComponent>
The line here is passed to child from Parent!!!
</ChildComponent>
//ChildComponent.razor
<h4>Child Component</h4>
<p>@ChildContent</p> @functions{
[Parameter]
private RenderFragment ChildContent { get; set; }
}

方式 2

RenderFragment 主要用于模板化目的,并基于子组件内部的逻辑呈现内容。

//ParentComponent.razor
<h3> Parent Component</h3>
<ChildComponent>
<SampleText>
<p>
<b>Bold Text here!!!</b>
</p>
</SampleText>
</ChildComponent>
//ChildComponent.razor
<h4>Child Component</h4>
<div>
@for(var i = 1; i <= 3; i++)
{
<h5>Line No : @i</h5>
<div>@SampleText</div>
}
</div> @functions{
[Parameter]
private RenderFragment SampleText { get; set; }
}

此时 SampleText 不是已经存在的组件,它是在父组件中的 ChildComponent tag元素中新生成的,同时在子组件中也声明了相同的命名为 SampleText 的属性。

SampleText 中的文本在子组件里循环渲染3次,这非常有助于创建模板组件、表格等。

Study Blazor .NET(四)数据绑定的更多相关文章

  1. ASP.NET Core Blazor Webassembly 之 数据绑定

    上一次我们学习了Blazor组件相关的知识(Asp.net Core Blazor Webassembly - 组件).这次继续学习Blazor的数据绑定相关的知识.当代前端框架都离不开数据绑定技术. ...

  2. Study Blazor .NET(三)组件

    翻译自:Study Blazor .NET,转载请注明. 关于组件 blazor中组件的基础结构可以分为以下3部分, //Counter.razor //Directives section @pag ...

  3. Study Blazor .NET(二)安装

    翻译自:Study Blazor .NET,转载请注明. 安装 请根据下面步骤安装开始使用Blazor: 1.针对不同的操作系统,安装最新版.Net Core框架 [这里] 2.用.Net Core ...

  4. Study Blazor .NET(一)简介

    翻译自:Study Blazor .NET,转载请注明. 介绍 Blazor是一个全新的 Web UI 框架,它使用c# .Razor 和 HTML以及 WebAssembly W3C标准.它提供了用 ...

  5. .NET Core 3.0预览版7中的ASP.NET Core和Blazor更新

    .NET Core 3.0 Preview 7现已推出,它包含一系列ASP.NET Core和Blazor的新更新. 以下是此预览中的新功能列表: 最新的Visual Studio预览包括.NET C ...

  6. [推荐]大量 Blazor 学习资源(一)

    前言 / Introduction Blazor 是什么? Blazor 允许您使用 C# 而不是 JavaScript 构建交互式 Web UI. Blazor 应用由使用 C#.HTML 和 CS ...

  7. ASP.NET Core Blazor Webassembly 之 路由

    web最精妙的设计就是通过url把多个页面串联起来,并且可以互相跳转.我们开发系统的时候总是需要使用路由来实现页面间的跳转.传统的web开发主要是使用a标签或者是服务端redirect来跳转.那今天来 ...

  8. Python3 数据类型-字典

    字典是一种可变数据类型,且可存储任意类型对象. 字典使用大括号"{}"括起来,由键(key)和值(values)组成,键只能使用不可变类型定义,值可以使用可变类型{'键':'值'} ...

  9. 微信小程序入门文档

    一 基本介绍 微信专门为小程序开发了一个ide叫做微信开发者工具 最新一版的微信开发者工具,把微信公众号的调试开发工作也集成了进去,可以更换开发模式. https://mp.weixin.qq.com ...

随机推荐

  1. 从零入门 Serverless | 教你使用 IDE/Maven 快速部署 Serverless 应用

    作者 | 许成铭(竞霄) 阿里云开发工程师 SAE 应用部署方式 1. SAE 概述 首先,简单介绍一下 SAE.SAE 是一款面向应用的 Serverless PaaS 平台,支持 Spring C ...

  2. 题解 「ZJOI2018」历史

    题目传送门 Description 九条可怜是一个热爱阅读的女孩子. 这段时间,她看了一本非常有趣的小说,这本小说的架空世界引起了她的兴趣. 这个世界有 \(n\) 个城市,这 \(n\) 个城市被恰 ...

  3. Mybatis 二级缓存应用 (21)

    [MyBatis 二级缓存] 概述:一级缓存作用域为同一个SqlSession对象,而二级缓存用来解决一级缓存不能夸会话共享,作用范围是namespace级,可以被多个SqlSession共享(只要是 ...

  4. FastAPI 学习之路(三十七)元数据和文档 URL

    你可以在 FastAPI 应用中自定义几个元数据配置. 你可以设定: Title:在 OpenAPI 和自动 API 文档用户界面中作为 API 的标题/名称使用. Description:在 Ope ...

  5. 初学Python “登录”案例 更新!!

    更新内容:添加了登录次数,如果超过限制的次数,则提示账户被锁定,去某邮箱申请解锁账户! 此次仅把登录系统更新之后源代码放到这里,不在共享源文件在网盘了! 1 ''' 2 登录界面 3 ''' 4 5 ...

  6. 第五课第四周实验一:Embedding_plus_Positional_encoding 嵌入向量加入位置编码

    目录 变压器预处理 包 1 - 位置编码 1.1 - 位置编码可视化 1.2 - 比较位置编码 1.2.1 - 相关性 1.2.2 - 欧几里得距离 2 - 语义嵌入 2.1 - 加载预训练嵌入 2. ...

  7. [对对子队]会议记录4.18(Scrum Meeting9)

    今天已完成的工作 何瑞 ​ 工作内容:修复了一些关卡1的bug ​ 相关issue:搭建关卡1 ​ 相关签入:4.18签入1 4.18签入2 梁河览 ​ 工作内容:实现了音量控制,添加了BGM ​ 相 ...

  8. 北航OO第三单元总结

    JML基础梳理及工具链 JML的全称是Java Modeling language,即Java建模语言.JML是一种行为接口规格.它为严格的程序设计提供了一套行之有效的方法.通过JML不仅可以基于规格 ...

  9. Python触发异常

    我们可以使用raise语句自己触发异常,raise语法格式如下: raise [Exception [, args [, traceback]]] 语句中 Exception 是异常的类型(例如,Na ...

  10. 对JavaScript中局部变量、全局变量和闭包的理解

    对js中局部变量.全局变量和闭包的理解 局部变量 对于局部变量,js给出的定义是这样的:在 JavaScript函数内部声明的变量(使用 var)是局部变量,所以只能在函数内部访问它.(该变量的作用域 ...