css - 为什么 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 中一样移动表格上方的搜索框?
解决方案
问题是 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;
}
}