将数据列表从组件发布到新组件,并在Blazor中呈现新组件

时间:2020-04-22 21:29:50

标签: asp.net-mvc blazor blazor-server-side asp.net-blazor

问题

用户从ComponentA中选择项目列表,然后查看所选项目列表。用户将被重定向到ComponentB,用户可以在其中找到所选项目的列表。

在MVC中

这很简单,因为我们可以简单地将View中的数据列表发布到Controller的Post方法中,然后可以从该控制器中呈现所需的新视图。

How can we accomplish the same in the Blazor Server?

请让我知道是否需要添加更多详细信息。

2 个答案:

答案 0 :(得分:2)

您可以尝试将两个组件都包装在外部组件中,然后将外部组件用作状态容器。

容器

<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>

答案 1 :(得分:2)

您可以根据ComponentA和ComponentB两者是否都是可路由组件的不同方式来完成此操作。

如果ComponentB是ComponentA的子组件;也就是说,不可路由的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:

<button type="button" @onclick="ShowList">Show list of women</button>

@code
{
   private void ShowList()
  {
      NavigateManager.NavigateTo("/ComponentB");
  }
}

如您所见,以上代码将用户从一页重定向到另一页,但是如何传递数据?为此,您必须定义一个服务类,该服务类可以注入两个组件中,以执行从一个组件到另一个组件的数据传递。 following link是我的回答,我在其中详细介绍了此机制。

希望这对您有帮助...