Blazor - 如何删除子组件
Blazor - how to remove a child component
背景
我有一个带有多个按钮的组件 MainComponent
,这将使新的 SubComponent
出现 (<TaskList AreaId="@SelectedAreaId" IsVisible="@IsVisible"></TaskList>
)。
问题
当我想在 SubComponent
上放置一个关闭按钮时出现问题:我尝试在其上创建一个按钮并制作:IsVisible = !IsVisible
。虽然这在某种程度上确实有效(它使组件从视图中消失),但它有一个问题,如果我用相同的 SubComponent
从 MainComponent
单击按钮,它不会出现(我假设因为组件仍然“活着”)。
最好的解决办法是什么?我正在考虑在 SubComponent
上使用 IDisposable
,但未定义 ComponentName.Dispose()
。
Edit1: 添加了我当前正在做的示例
主要组件 (TaskList.razor)
<div class="col-12 outer-div row">
<TaskDetails TaskId="@SelectedTaskId" IsVisible="@IsTaskDetailsVisible"></TaskDetails>
</div>
...
<ul>
@for (int i = 0; i < MondayTasks.Count(); i++)
{
var myIndex = i;
<li class="btn" @onclick="@(() => LoadTaskDetailsForTask(MondayTasks[myIndex].Id))">
<a role="button">
<h4>@MondayTasks[i].Name</h4>
<p>@MondayTasks[i].DeadlineDate.Date.ToShortDateString()</p>
</a>
</li>
}
</ul>
...
private async Task LoadTaskDetailsForTask(int taskId)
{
SelectedTaskId = taskId;
IsTaskDetailsVisible = true;
await JSRuntime.InvokeVoidAsync("onScrollEvent");
}
子组件 (TaskDetails.razor)
@if (IsVisible)
{
...
<div class="row">
<h2 class="inner-div title">@taskDetails.Name</h2>
<span class="closebtn" @onclick="()=> ToggleVisibility()">×</span>
</div>
//Display Information
}
...
protected async override void OnParametersSet()
{
taskDetails = await _dbTasks.GetTasksDetails(TaskId);
TaskItems = await _dbTasks.GetTasksItems(TaskId);
this.StateHasChanged();
}
private void ToggleVisibility()
{
IsVisible = !IsVisible;
}
Edit2: 添加了工作代码
主要组件 (TaskList.razor)
<CascadingValue Value="this">
<div class="col-12 outer-div row">
<TaskDetails TaskId="@SelectedTaskId" IsVisible="@IsTaskDetailsVisible"></TaskDetails>
</div>
</CascadingValue>
...
<ul>
@for (int i = 0; i < MondayTasks.Count(); i++)
{
var myIndex = i;
<li class="btn" @onclick="@(() => LoadTaskDetailsForTask(MondayTasks[myIndex].Id))">
<a role="button">
<h4>@MondayTasks[i].Name</h4>
<p>@MondayTasks[i].DeadlineDate.Date.ToShortDateString()</p>
</a>
</li>
}
</ul>
...
private async Task LoadTaskDetailsForTask(int taskId)
{
SelectedTaskId = taskId;
IsTaskDetailsVisible = true;
await JSRuntime.InvokeVoidAsync("onScrollEvent");
}
public void RemoveTaskDetails()
{
IsTaskDetailsVisible = false;
StateHasChanged();
}
子组件 (TaskDetails.razor)
@if (IsVisible)
{
...
<div class="row">
<h2 class="inner-div title">@taskDetails.Name</h2>
<span class="closebtn" @onclick="()=> ToggleVisibility()">×</span>
</div>
//Display Information
}
...
[CascadingParameter]
public TaskList _Parent { get; set; }
protected async override void OnParametersSet()
{
taskDetails = await _dbTasks.GetTasksDetails(TaskId);
TaskItems = await _dbTasks.GetTasksItems(TaskId);
this.StateHasChanged();
}
private void ToggleVisibility()
{
_Parent.RemoveTaskDetails();
}
你有
[Parameter] bool IsVisible {get; set; }
private void ToggleVisibility()
{
IsVisible = !IsVisible;
}
应避免这种模式:不要从组件内部更改参数。
您将必须添加 EventCallback 并更改主要组件上的 IsTaskDetailsVisible。
背景
我有一个带有多个按钮的组件 MainComponent
,这将使新的 SubComponent
出现 (<TaskList AreaId="@SelectedAreaId" IsVisible="@IsVisible"></TaskList>
)。
问题
当我想在 SubComponent
上放置一个关闭按钮时出现问题:我尝试在其上创建一个按钮并制作:IsVisible = !IsVisible
。虽然这在某种程度上确实有效(它使组件从视图中消失),但它有一个问题,如果我用相同的 SubComponent
从 MainComponent
单击按钮,它不会出现(我假设因为组件仍然“活着”)。
最好的解决办法是什么?我正在考虑在 SubComponent
上使用 IDisposable
,但未定义 ComponentName.Dispose()
。
Edit1: 添加了我当前正在做的示例
主要组件 (TaskList.razor)
<div class="col-12 outer-div row">
<TaskDetails TaskId="@SelectedTaskId" IsVisible="@IsTaskDetailsVisible"></TaskDetails>
</div>
...
<ul>
@for (int i = 0; i < MondayTasks.Count(); i++)
{
var myIndex = i;
<li class="btn" @onclick="@(() => LoadTaskDetailsForTask(MondayTasks[myIndex].Id))">
<a role="button">
<h4>@MondayTasks[i].Name</h4>
<p>@MondayTasks[i].DeadlineDate.Date.ToShortDateString()</p>
</a>
</li>
}
</ul>
...
private async Task LoadTaskDetailsForTask(int taskId)
{
SelectedTaskId = taskId;
IsTaskDetailsVisible = true;
await JSRuntime.InvokeVoidAsync("onScrollEvent");
}
子组件 (TaskDetails.razor)
@if (IsVisible)
{
...
<div class="row">
<h2 class="inner-div title">@taskDetails.Name</h2>
<span class="closebtn" @onclick="()=> ToggleVisibility()">×</span>
</div>
//Display Information
}
...
protected async override void OnParametersSet()
{
taskDetails = await _dbTasks.GetTasksDetails(TaskId);
TaskItems = await _dbTasks.GetTasksItems(TaskId);
this.StateHasChanged();
}
private void ToggleVisibility()
{
IsVisible = !IsVisible;
}
Edit2: 添加了工作代码
主要组件 (TaskList.razor)
<CascadingValue Value="this">
<div class="col-12 outer-div row">
<TaskDetails TaskId="@SelectedTaskId" IsVisible="@IsTaskDetailsVisible"></TaskDetails>
</div>
</CascadingValue>
...
<ul>
@for (int i = 0; i < MondayTasks.Count(); i++)
{
var myIndex = i;
<li class="btn" @onclick="@(() => LoadTaskDetailsForTask(MondayTasks[myIndex].Id))">
<a role="button">
<h4>@MondayTasks[i].Name</h4>
<p>@MondayTasks[i].DeadlineDate.Date.ToShortDateString()</p>
</a>
</li>
}
</ul>
...
private async Task LoadTaskDetailsForTask(int taskId)
{
SelectedTaskId = taskId;
IsTaskDetailsVisible = true;
await JSRuntime.InvokeVoidAsync("onScrollEvent");
}
public void RemoveTaskDetails()
{
IsTaskDetailsVisible = false;
StateHasChanged();
}
子组件 (TaskDetails.razor)
@if (IsVisible)
{
...
<div class="row">
<h2 class="inner-div title">@taskDetails.Name</h2>
<span class="closebtn" @onclick="()=> ToggleVisibility()">×</span>
</div>
//Display Information
}
...
[CascadingParameter]
public TaskList _Parent { get; set; }
protected async override void OnParametersSet()
{
taskDetails = await _dbTasks.GetTasksDetails(TaskId);
TaskItems = await _dbTasks.GetTasksItems(TaskId);
this.StateHasChanged();
}
private void ToggleVisibility()
{
_Parent.RemoveTaskDetails();
}
你有
[Parameter] bool IsVisible {get; set; }
private void ToggleVisibility()
{
IsVisible = !IsVisible;
}
应避免这种模式:不要从组件内部更改参数。
您将必须添加 EventCallback 并更改主要组件上的 IsTaskDetailsVisible。