0

问题

用户从中选择项目列表,ComponentA然后查看所选项目列表。用户被重定向到ComponentB用户找到所选项目列表的位置。

在 MVC 中

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

How can we accomplish the same in the Blazor Server?

如果需要添加更多详细信息,请告诉我。

4

2 回答 2

2

您可以通过各种方式执行此操作,具体取决于 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;} 
} 

如您所见,我们将年龄和国家/地区值从父组件传递给它的子组件。在现实生活中的代码中,您可能会传递对象集合、进行各种操作等。以上是父母如何与孩子沟通并传递值的基本概述。反过来,也就是将值从子组件传递到其父组件是通过事件委托完成的。

当两个组件都是组件页面时;也就是说,两者都是可路由的,您通常需要一个中介对象来执行将值从一个组件传递到另一个组件。

假设您想将您的用户从当前页面重定向到 ComponentA,例如 ComponentA,他在其中填写了一个包含大量数据项的表单,ComponentB 获取数据,处理数据等。这是如何从 ComponentA 导航到 Navigate 的代码到组件B:

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

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

如您所见,上面的代码将用户从一个页面重定向到另一个页面,但是如何传递数据呢?为了实现这一点,您必须定义一个可以注入到两个组件中的服务类,以执行数据从一个到另一个的传递。以下链接是我的一个答案,我在其中详细介绍了这种机制。

希望这可以帮助...

于 2020-04-22T22:58:45.147 回答
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 派生并为您提供一个由您需要设置的布尔值过滤的列表。为了将关注点放在正确的位置,所有针对列表的函数也应该存在于 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>.

于 2020-04-22T22:50:32.443 回答