首页 > 解决方案 > 为什么 tbody 中的元素没有移到表格上方

问题描述

我已将这篇文章中的过滤器组件添加到默认的 Blazor 天气示例中。它工作正常,但搜索输入显示在表格的第一行中。

<tbody>
  <FilterableTable Items=@forecasts GetFilterableText=@(item => item.Summary)>
    <tr>
      <td>@context.Date.ToShortDateString()</td>
      <td>@context.TemperatureC</td>
      <td>@context.TemperatureF</td>
      <td>@context.Summary</td>
    </tr>
  </FilterableTable>
</tbody>

有关完整代码,请参阅此小提琴

但是,当我将生成的 HTML 放入带有 Bootstrap 的 JS 小提琴中时,输入会显示在表格上方。

<tbody>
  <input class="filterbox" placeholder="filter">
  <tr>
    <td>06/05/2018</td>
    <td>1</td>
    <td>33</td>
    <td>Freezing</td>
  </tr>
</tbody>

有关完整代码,请参阅此小提琴

我错过了什么吗?是否有一些引导 JS 魔法可以移动 Blazor Server 中缺少的输入?我怎么能像在 JSFiddle 中一样移动表格上方的搜索框?

标签: cssblazorblazor-server-side

解决方案


问题是 FilterableTable 组件包含 input 元素,并且 FilterableTable 组件正在 tbody html 元素中呈现。您应该遵循如何创建模板化组件的设计标准。这是一个如何解决您的问题的工作示例。请注意,我很快就编写了这段代码,并且可能需要一些改进。

索引.razor

@page "/"
@inject HttpClient Http
@inject NavigationManager NavigationManager

<h1>Weather forecast</h1>

<p>This component demonstrates fetching data from the server.</p>

@if (forecasts == null)
{
    <p><em>Loading...</em></p>
}
else
{
    <a class="btn" href="/create">
        <i class="oi oi-plus"></i>
        Add new item
    </a>

<FilterableTable Items=@forecasts GetFilterableText=@(item => item.Summary)>

    <TableHeader>
        <tr>
            <th>Date</th>
            <th>Temp. (C)</th>
            <th>Summary</th>
        </tr>

    </TableHeader>
 
     <RowTemplate>
                    <td>@context.Date.ToShortDateString()</td>
                    <td>@context.TemperatureC</td>
                    <td>@context.Summary</td>
     </RowTemplate>
  
</FilterableTable>
}
@functions {
    WeatherForecast[] forecasts;

    protected override async Task OnInitializedAsync()
    {
        await base.OnInitializedAsync();
        forecasts = await Http.GetFromJsonAsync<WeatherForecast[]>(NavigationManager.ToAbsoluteUri("/sample-data/weather.json").ToString());
    }

    class WeatherForecast
    {
        public DateTime Date { get; set; }
        public int TemperatureC { get; set; }
        public int TemperatureF { get; set; }
        public string Summary { get; set; }
    }
}

FilterableTable.razor

@typeparam TItem

<p><input class="filterbox" @bind=Filter @bind:event="oninput" placeholder="filter" /></p>
<br />
<table class="table">
    <thead>
          @TableHeader
    </thead>
       
    <tbody>
        @foreach (TItem item in GetFilteredItems())
        {
            <tr>
               @RowTemplate(item)
         
            </tr>
         }
     </tbody>
</table>  

    @code {
        [Parameter]
        public RenderFragment TableHeader { get; set; }

        [Parameter] public IEnumerable<TItem> Items { get; set; }
        [Parameter] public Func<TItem, string> GetFilterableText { get; set; }
        [Parameter] public RenderFragment<TItem> RowTemplate { get; set; }

        private string Filter;

        private static readonly Func<TItem, string> DefaultGetFilterableText = item => (item?.ToString() ?? string.Empty);

        private IEnumerable<TItem> GetFilteredItems()
        {
            Func<TItem, string> filterFunc = GetFilterableText ?? DefaultGetFilterableText;
            IEnumerable<TItem> result = (Items ?? Array.Empty<TItem>());
            if (!string.IsNullOrEmpty(Filter))
            {
                result = result.Where(x => (GetFilterableText(x) ?? string.Empty).Contains(Filter,
                  StringComparison.InvariantCultureIgnoreCase));
            }

            return result;
        }
    }

推荐阅读