问题
用户选择项目列表,从 ComponentA
然后查看所选项目的列表。用户会被重定向到 ComponentB
其中,用户可以找到所选项目的列表。
在MVC中
这很直接,因为我们可以简单地将数据列表从View发布到Post方法的 Controller
并且从该控制器中我们可以呈现所需的新视图。
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 派生出来,并给你一个由你需要设置的布尔值过滤的列表。为了将关注点放在正确的地方,所有针对列表的函数也应该放在容器组件中。你还设置了对这两个组件的引用,这样你就可以在外部执行它们的公共方法。
要访问这些组件,为它们设置一个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>
.
根据ComponentA和ComponentB是否都是可路由的组件,你可以用不同的方式来实现。
如果ComponentB是ComponentA的子组件,也就是说,ComponentB(不可路由的)被嵌入到ComponentA中,你可以将ComponentA的值作为Component参数传递给ComponentB。以下代码片段创建了一个父组件和一个子组件,并演示了如何从父组件向子组件传递值。
@page "/parent"
<Child Age="age" Country="country" />
@code
{
private int age = 21;
private string country = "Thailand";
}
@ 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;}
}
如你所见,我们将年龄和国家的值从父组件传递给它的子组件。在实际的代码中,你可能会传递对象的集合,进行各种操作等。以上是一个基本的轮廓,即父组件如何与它的子组件通信,并向它传递值。另一种方式,就是要把子组件的值传递给父组件,是通过事件委托来完成的。
当两个组件都是Component页面时,也就是说,两者都是可路由的,你通常需要一个中介对象来执行从一个组件到另一个组件的传值。
假设你想把你的用户从当前页面(比如说ComponentA,他在这里填写了一个有很多数据项的表单)重定向到ComponentB,ComponentB获取数据,处理数据等等。下面是如何从ComponentA导航到ComponentB的代码。
<button type="button" @onclick="ShowList">Show list of women</button>
@code
{
private void ShowList()
{
NavigateManager.NavigateTo("/ComponentB");
}
}
正如你所看到的,上面的代码将用户从一个页面重定向到另一个页面,但是如何传递数据呢?为了达到这个目的,你必须定义一个服务类,这个服务类可以被注入到两个组件中,以执行数据从一个组件到另一个组件的传递。这个 下面的链接 是到我的一个答案,在那里我详细讲述了这个机制。
希望能帮到你...