问题
用户从ComponentA
中选择项目列表,然后查看所选项目的列表。用户被重定向到ComponentB
,在那里用户可以找到所选项目的列表。
在MVC中
这是直接的,因为我们可以简单地将View中的数据列表发布到Controller
的post方法,然后从该控制器中我们可以呈现所需的新视图。
How can we accomplish the same in the Blazor Server?
如果需要添加更多细节,请告诉我。
您可以尝试将两个组件封装在外部组件中,然后将外部组件用作状态容器。
容器
<div>
<ComponentA @ref="_componentA" ListItems="ListA"/>
<ComponentB @ref="_componentb" ListItems="ListB"/>
</div>
@code {
Public List<T> ListA { get; set; }
Public List<T> ListB => ListA.Where(x => x.IsSelected).ToList();
ComponentA _componentA;
ComponentB _componentB;
}
现在,您已经将列表与渲染细节分离,ListB只是从ListA派生而来,并为您提供了一个通过需要设置的布尔值过滤的列表。为了将关注点放在正确的位置,列表中的所有函数也应该位于Container组件中。您还设置了对2个组件的引用,这样您就可以在外部对它们的公共方法进行操作。
若要访问组件,请使用IsVisible属性和起始值、要显示和隐藏的方法以及EventCallBack
属性对它们进行设置,以便调用代码可以设置方法。您还需要一个回调控件(按钮?(。
组件A
<div style="display: @(IsVisible ? "flex" : "none")">
@foreach (var item in Items)
{
//Do something awesome
}
<button @onclick="@(() => ToggleToB.InvokeAsync())">Toggle to Component B</button>
</div>
@code {
[Parameter]
public List<T> Items { get; set; }
[Parameter]
public EventCallBack ToggleToB { get; set; }
private bool IsVisible { get; set } = true
public void Show()
{
IsVisible = true;
}
public void Hide()
{
IsVisible = false;
}
... other component details
}
组件B将具有相同的设置,但IsVisible的初始值将是false
,因为您最初不希望看到它。
现在,您可以从Container
中设置作用于组件方法的方法,因此您的容器如下所示。注意<Component>
标签中的回调方法:
容器更新
<div>
<ComponentA @ref="_componentA" ListItems="ListA" ToggleToB="@ShowComponentB"/>
<ComponentB @ref="_componentb" ListItems="ListB" ToggleToA="@ShowComponentA"/>
</div>
@code {
Public List<T> ListA { get; set; }
Public List<T> ListB => ListA.Where(x => x.IsSelected).ToList();
public ComponentA _componentA;
ComponentB _componentB;
public void ShowComponentA()
{
_componentA.Show();
_componentB.Hide();
}
public void ShowComponentB()
{
_componentB.Show();
_componentA.Hide();
}
public void ListBConfirmed()
{
// Do whatever you do once you go through Component B
ShowComponentA();
}
}
最后,请记住,组件A和B都不需要列出@page
,而是在路由的Container
中执行,因为容器中的每个组件现在都被设计成包装在容器中以捕获引用,并获得它的列表。
就这样,现在您有了组件A和B来渲染来自另一个源的列表,以及对来自外部源的方法执行操作以根据需要更新列表所需的所有管道。只需根据需要添加更多的EventCallBack
参数,如果有参数要传递给容器方法,请记住使用EventCallBack<T>
。
根据组件A和组件B是否都是可路由组件,可以通过各种方式来实现。
如果组件B是组件a的子组件;也就是说,不可路由的ComponentB嵌入在ComponentA中,您可以将ComponentA中的值作为Component参数传递给ComponentB。。。以下代码片段创建了一个父组件和一个子组件,并演示了如何将值从父组件传递到子组件:
Parent.razor
@page "/parent"
<Child Age="age" Country="country" />
@code
{
private int age = 21;
private string country = "Thailand";
}
Child.razor
@ No @page directive here as the child component is not routable @
<p>Country: @Country</p>
@code
{
[Parameter]
Public int Age {get; set;}
[Parameter]
Public string Country {get; set;}
}
正如您所看到的,我们将年龄和国家/地区值从父组件传递到其子组件。在现实生活中的代码中,您可以传递对象集合、进行各种操作等。以上是父级如何与其子级通信并传递值的基本概述。另一种方法是,通过事件代理将值从子组件传递给其父组件。
当两个组件都是组件页面时;也就是说,两者都是可路由的,您通常需要一个中介对象来执行从一个组件到另一个组件的值传递。
假设你想将用户从当前页面重定向到ComponentB,比如ComponentA,他在那里填写了很多数据项,ComponentB获取数据、处理数据等。以下是如何从ComponentA导航到ComponentB:
<button type="button" @onclick="ShowList">Show list of women</button>
@code
{
private void ShowList()
{
NavigateManager.NavigateTo("/ComponentB");
}
}
正如你所看到的,上面的代码将用户从一个页面重定向到另一个页面,但如何传递数据呢?为了实现这一点,您必须定义一个服务类,该服务类可以注入到两个组件中,以执行从一个组件到另一个组件的数据传递。以下链接是我的答案,我在其中详细介绍了这一机制。
希望这能帮助。。。