11.组件状态向外(消费者端)传递--自定义组件与消费端变量之间实现双向绑定
这也实现了从子组件到父组件的状态传递。
1.定义一个数据类型为T的参数。
2.再定义一个 参数名+[Changed]为名称,EventCallback
3.定义一个被用于元素中的C#事件触发的事件方法OnChanged,并在该事件方法中调用第2步中定义的EventCallback结构类型参数中的InvokeAsync(Text)成员方法。
4.写出元素中C#事件代码并绑定第3步中的事件方法。
注意: 3、4两步也可以以在4中写出lambda表达式的形式合成一步
这样做之后,则在组件的消费者调用端会按约定在组件内出现一个 @bind-[1步中参数名] 的绑定参数。
5. 以 @bind-[参数名]="[消费者中变量名]"
的形式将消费者变量与自定义组件的绑定参数相绑定即可。
代码如下:
- 自定义组件代码:
<input type="text" value="@Text" @onchange="Onchanged" />
@code
{
[parameter]public string? Text {get;set;}
[parameter]public EventCallback<string?> TextChanged {get;set;}
Task Onchanged(ChangeEventArgs e)
{
Text = e.Value?.ToString();
TextChanged.InvokeAsync(Text);
return Task.CompletedTask;
}
}
- 消费者代码或说调用者代码:
@page "/custom-bind"
<CustomComponent @bind-Text="ConsumerVariate" />
<h3>@ConsumerVariate<h3>
@code
{
string? ConsumerVariate {get;set}
}
12.组件的任意参数
组件参数典型用途就是用来做html元素的各种属性(Attribute)的载体,html元素众多而且个数任意,所以组件参数会很多,并且组件参数很多时候是由外部消费者传进来的,这时我们无法事先定义所有参数而需要能有某个东西能一次承载所有参数或说html属性。
这时Blazor的组件属性Attributes
就被设计出来了,它可以绑定在一个C#字典类型的参数,如Dictionary<string,object>
。
使用规则如下:
- 组件中需声明一个
Dictionary<string,object>?
类型的参数,该参数可以在 Parameter特性标签中传入参数(CaptureUnmatchedValues=true)
用来表示当外部传入html属性给字典后,如果字典中元素不匹配组件中显式写的参数,则在生成html时也自动把它展开并附中这些属性到html元素。 - 组件中的html元素中用
@attributes="@Attributes"
写在html元素属性位置,表示将来从Attributes
字典元素自动生成一系列的html属性和属性值对,在blazor技术中这叫属性的展开。 - 外部调用者在调用组件时,直接像写普通的html元素的属性一样的逐个写出【属性=属性值】对即可。
以下是示例代码:
组件的:
<input type="text" value="@Text" class="form-control @(Class)" @arttributes="@Attributes"/>
@code
{
[Parameter]public string? Text{get;set;}
[Parameter]public string? Class{get;set;}
[Parameter(CaptureUnmatchedValues=true)]public Dictionary<string,object>? Attributes{get;set;}
}
外部调用者
@Page "/any-attributes"
<AnyAttributesControl Class="form-control-md" title="大文本框" style="color:blue">
说明:
- 参数Class与组件中显示参数相匹配,会生成在html元素属性中;
- 组件中Text参数被调用者忽略,由于Text是可为空类型,所以将来它不会生成在html元素属性列表中;
- 其它title、style两个属性不与组件显示参数匹配,但是由于组件中属性字典参数
Attributes
显示指明(CaptureUnmatchedValues=true)
所以,会被生成在html元素属性中。