【问题标题】:Simple expandable table with Blazor使用 Blazor 的简单可扩展表
【发布时间】:2021-08-08 04:08:30
【问题描述】:

我想在 Blazor WebAssembly 中创建一个简单的可扩展表。我添加了一些 HTML 代码,如下所示:

<table class="table table-hover">
  <thead>
    <tr>
      <th>#</th>
      <th>User</th>
      <th>Date</th>
      <th>Status</th>
      <th>Reason</th>
    </tr>
  </thead>
  <tbody>
    <tr data-widget="expandable-table" aria-expanded="false">
      <td>183</td>
      <td>John Doe</td>
      <td>11-7-2014</td>
      <td>Approved</td>
      <td>Lorem Ipsum is simply dummy text</td>
    </tr>
    <tr class="expandable-body">
      <td colspan="5">
        <p>
          Lorem Ipsum is simply dummy text
        </p>
      </td>
    </tr>
  </tbody>
</table>

如果我点击它,带有详细信息的行也会被折叠。有没有不使用外部组件的简单方法来实现它?如果没有,您推荐什么组件?

我所说的“可扩展表”的一个例子是here

【问题讨论】:

  • 您为什么期望纯 HTML 在这里发生任何事情? data-widget="expandable-table" 应该做什么
  • 我以这张表为例。我从一个 api 重试数据并呈现一个类似于这个的表。当我必须创建一个可扩展的表时,通常使用 Bootstrap 我添加这个data-
  • 目前尚不清楚这与 Blazor 有何关系。除了您的标签之外,没有任何迹象表明除了 html 之外的语言或技术。还不清楚您要实施什么。 “可扩展表”是什么意思?
  • 天哪,你们简直是卑鄙的。我有时讨厌 StackOverflow...

标签: blazor blazor-webassembly


【解决方案1】:

使用 Bootstrap,内置的 jQuery/JavaScript 代码不会像传统 MVC 页面那样开箱即用。

如果要展开/折叠行,Blazor 有两个选项。

  1. 通过将 IJSRuntime 注入页面并调用 InvokeAsync() 来调用 Bootstrap jQuery/JavaScript。

  2. 编写您自己的展开/折叠组件并将每一行包装在其中 - 类似于

// CollapsibleTableRow.

<tr @onclick=Toggle>
   @if(_show)
   {
       @ChildContent
   }
</tr>


@code 
{
    [Parameter] public RenderFragment ChildContent { get; set; }
    private bool _show { get; set; } = false;
    
    private void Toggle()
    {
        _show = !_show;
    }
}

使用

<table>
    <tbody>
         @foreach(var item in items)
         {
             <CollapsibleTableRow>
                 <td>@item.Thing</td>
                 <td>@item.Thing2</td>
             </CollapsibleTableRow>
         }
    </tbody>
</table>

【讨论】:

  • 感谢您的回答。它是如何工作的?在一个表中有很多行。 Toggle 每行是否唯一?
  • 是的,会为表格中的每一行渲染一个 CollapsibleTableRow 组件,每行都有自己的内部切换。
  • 为您添加了非常简单的示例。
【解决方案2】:

我提出了一个基于来自 Blazor Server 模板的默认“WeatherForecast”的解决方案。基本思想是在模型中放置一个标志,用于表示表格数据。

WeatherForecast.cs

public class WeatherForecast
{
    public DateTime Date { get; set; }

    public int TemperatureC { get; set; }

    public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);

    public string Summary { get; set; }

    //new fields added below
    public bool IsRowExpanded { get; set; } = false;

    public string ExpandableContent { get; set; } = "Lorem Ipsum";
}

FetchData.razor

<table class="table">
    <thead>
        <tr>
            <th>Date</th>
            <th>Temp. (C)</th>
            <th>Temp. (F)</th>
            <th>Summary</th>
        </tr>
    </thead>
    <tbody>
        @foreach (var forecast in forecasts)
        {
            <tr @onclick="() => forecast.IsRowExpanded = !forecast.IsRowExpanded">
                <td>@forecast.Date.ToShortDateString()</td>
                <td>@forecast.TemperatureC</td>
                <td>@forecast.TemperatureF</td>
                <td>@forecast.Summary</td>
            </tr>
            if (forecast.IsRowExpanded)
            {
                <tr>@forecast.ExpandableContent</tr>
            }
        }
    </tbody>
</table>

当您点击一行(例如第二行)时,它会如下所示:

【讨论】:

    【解决方案3】:

    更新的答案。我添加了一个小类以使其更容易。神奇之处在于我称之为“状态载体变量”,它允许您将打开状态设为Person 类的属性,而不是添加单独的列表来跟踪哪些行被打开或未打开。键入它需要一些时间,所以如果你喜欢它,请记得将其标记为“已回答”。

    @page "/collapse"
    
    <table class="table">
        <thead>
            <tr style="cursor:pointer;">
                <th>#</th>
                <th>User</th>
                <th>Date</th>
                <th>Status</th>
                <th>Reason</th>
            </tr>
        </thead>
        <tbody>
            @foreach (Person person in People)
            {
                <tr style="cursor:pointer" @onclick="()=>person.opened=!person.opened">
                    <td>@person.id</td>
                    <td>@person.name</td>
                    <td>@person.birthday.ToString("dddd MMMM d, yyyy")</td>
                    <td>@(person.approved ? "Approved" : "Denied")</td>
                    <td>@person.reason</td>
                </tr>
                @if (person.opened)
                {
                    <tr>
                        <td colspan="5">
                            <p>
                                Lorem Ipsum is simply dummy text
                            </p>
                        </td>
                    </tr>
                }
            }
        </tbody>
    </table>
    
    @code {
        class Person
        {
            public int id;
            public string name;
            public DateTime birthday;
            public bool approved;
            public string info;
            public string reason;
            public bool opened;  // I call this a state carrier, because it's not really data.
    
            public Person(int ID, string Name, DateTime Birthday, bool Approved, string Reason) {
                id = ID; name = Name; birthday = Birthday; approved = Approved; reason = Reason;
            }
        }
        List<Person> People = new List<Person>();
    
        protected override void OnInitialized()
        {
            People.Add(new Person(183, "John Doe", new DateTime(2014, 7, 11), true, "Good worker."));
            People.Add(new Person(184, "Benjamin", new DateTime(1999, 9, 9), false, "Types too much."));
            People.Add(new Person(1, "Jesus", new DateTime(1, 1, 1), true, "Really nice guy."));
        }
    }
    

    【讨论】:

    • 感谢您的回答。我不想点击标题,而是点击行。当我单击一行时,我想显示它的详细信息。这种表格的一个例子是adminlte.io/themes/v3/pages/tables/simple.html
    • 具体细节无所谓。您可以将“@onclick”放在几乎任何您想要的 html 上,并隐藏/显示您想要的任何内容。让我在单独的答案中举一个更简单的例子。
    • 好的,我给你一个完成的例子。打出来花了一些时间,所以如果你喜欢,请记得接受它作为答案。
    • 我的回答与您链接中的示例完全相同。选择它作为答案有什么问题吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-08-18
    • 2017-02-08
    • 1970-01-01
    • 2020-05-02
    • 1970-01-01
    • 2014-03-12
    • 1970-01-01
    相关资源
    最近更新 更多