toc*_*lle 6 dependency-injection blazor blazor-server-side asp.net-core-3.0 blazor-client-side
我想在 Blazor 中做一些我通常在 React 中做的事情:创建一个内部使用其他子组件的可重用组件,并能够将这些子组件作为参数传递。我需要能够将子组件视为依赖项,可以按需注入不同上下文中可能需要的任何自定义实现。
想象一下,例如,一个TextBox.razor组件,只要它实现了一个ILabel接口,你就可以传递一个自定义组件来根据需要呈现标签。我尝试过这样的事情,但语法似乎无效:
正如您从屏幕截图中看到的,Blazor 不允许我将参数Label用作组件。知道如何实现这一目标吗?
您应该能够使用模板化组件来完成此操作。
文本框.razor
@typeparam inputType
<div class="textbox">
@if(LabelTemplate!=null && TItem!=null)
@LabelTemplate(TItem)
<input type="text"/>
</div>
@code{
[Parameter]
public RenderFragment<inputType> LabelTemplate { get; set; }
[Parameter]
public inputType TItem { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
在上面的代码中,您指定组件使用@typeparam inputType并接收该类型的对象作为参数来接受类型TItem。
您还接受 a LabelTemplate,它接受类型为 的对象inputType。为了渲染这个片段,我们调用@LabelTemplate并传入我们的TItem参数。
现在让我们看看如何在名为 PersonForm.razor 的新组件中使用我们的模板化组件
PersonForm.razor
<Textbox TItem="myPerson">
<LabelTemplate>
@context.Name
</LabelTemplate>
</Textbox>
<Textbox TItem="myPerson">
<LabelTemplate>
@context.PhoneNumber
</LabelTemplate>
</Textbox>
@code{
Person myPerson = new Person { Name = "Jane Doe", PhoneNumber = "999 999 9999" };
public class Person
{
public string Name { get; set; }
public string PhoneNumber { get; set; }
}
}
Run Code Online (Sandbox Code Playgroud)
我将我的 Person 对象传递给每个 Textbox 组件的 TItem 属性,并使用@context语法在 LabelTemplate 中访问它。
起初这可能看起来很混乱,所以请在这里阅读
编辑 它只取决于你想完成什么。Verbose 语法为组件的“实现”方面带来了灵活性。您不是强制使用可能不适用于各种模型/类的接口,而是让实现指定要做什么。
如果您想要不那么冗长/更严格的内容,您也可以执行以下操作。
@implements ILabel
<div class="textbox">
<label>@Text</label>
<input type="text"/>
</div>
@code
{
[Parameter]
public string Text { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
标签文件
public interface ILabel
{
string Text { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
我意识到这可能已经晚了,但我只是挣扎着解决这个问题,发现这非常简单!我想我会为正在寻找的人提供一个简单的答案。
这是我的OrdersNavigation.razor文件(我想将其嵌入到标头中):
<div class="nav-strip">
<NavLink href="orders">
<Icon Name="@Icons.Cart" /> List
</NavLink>
<NavLink href="orders/create">
<Icon Name="@Icons.Plus" /> Create
</NavLink>
</div>
Run Code Online (Sandbox Code Playgroud)
现在这是我的PageHeader.razor:
<div class="page-header">
<h3>@Title</h3>
@Navigation
</h3>
<hr />
@code {
[Parameter] public string Title { get; set; } = "[TITLE]";
[Parameter] public RenderFragment Navigation { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
请注意,Navigation属性是一个RenderFragment - 这是关键。现在在我的页面中,我可以简单地添加它,如下所示:
<PageHeader Title="Orders">
<Navigation>
<OrderNavigation />
</Navigation>
</PageHeader>
Run Code Online (Sandbox Code Playgroud)
您在此处看到Title参数像往常一样输入,但Navigation参数作为PageHeader的元素输入!真的,你可以把任何东西放进去标签,它将在您有@Navigation 的位置呈现。
试了一下你的例子:
标签.剃须刀
<label>@Text</label>
@code {
[Parameter] public RenderFragment Text { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
文本框.razor
<div class="textbox">
<Label>
<Text>
<div>
Embedded label <br />
You can even drop components in here!
</div>
</Text>
</Label>
<input />
</div>
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4222 次 |
| 最近记录: |