Replies: 1 comment
-
I think I have figured it out: -- TabsItem.razor
@implements IDisposable
<div style="@GetStyle()" @onclick="HandleClick">
@Name - <span style="color: palevioletred">@selectedInternally</span>
</div>
@code {
private bool selectedInternally;
[CascadingParameter]
private Tabs? Container { get; set; } = null;
[Parameter]
public string Name { get; set; } = string.Empty;
[Parameter]
public RenderFragment? ChildContent { get; set; }
[Parameter]
public bool Selected { get; set; }
[Parameter]
public EventCallback<bool> SelectedChanged { get; set; }
public async Task Deselect()
{
if (selectedInternally)
{
Console.WriteLine($"Deselecting {Name}");
selectedInternally = false;
await SelectedChanged.InvokeAsync(false);
}
}
public void Dispose()
{
Container?.RemoveItem(this);
}
public override async Task SetParametersAsync(ParameterView parameters)
{
var hasSelectionChanged = parameters.TryGetValue<bool>(nameof(Selected), out var isSelectedNow) && isSelectedNow != Selected;
await base.SetParametersAsync(parameters);
Console.WriteLine($"Hitting {nameof(SetParametersAsync)} for {Name}");
if (hasSelectionChanged)
{
selectedInternally = isSelectedNow;
Console.WriteLine($"Toggling selection of {Name} from {nameof(SetParametersAsync)} to {selectedInternally}");
await OnSelectionChange();
}
}
protected override async Task OnInitializedAsync()
{
await base.OnInitializedAsync();
selectedInternally = Selected;
if (Container is not null)
{
await Container.AddItem(this);
}
else
{
Console.WriteLine($"Container was null for {Name}");
}
}
private async Task HandleClick()
{
if (!selectedInternally)
{
Console.WriteLine($"Handling click on {Name}");
selectedInternally = true;
await OnSelectionChange();
await SelectedChanged.InvokeAsync(true);
}
else
{
Console.WriteLine($"Ignoring click on {Name}");
}
}
private async Task OnSelectionChange()
{
if (Container is not null)
await (selectedInternally ? Container.SelectItem(this) : Container.DeselectItem(this));
}
private string GetStyle() => $"background-color: #1b6ec2; color: white; height: 2rem; width: {Name.Length + 10}ch; text-align: center; cursor: pointer";
} I wonder whether it is the cleanest solution. |
Beta Was this translation helpful? Give feedback.
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
I have troubles implementing my blazor component, because whenever it is rendered changes it has made to own parameters are overwritten by parent. Why it is happening and why I should not mutate own [Parameter] properties have been described in:
https://learn.microsoft.com/en-us/aspnet/core/blazor/components/data-binding?view=aspnetcore-8.0#bind-across-more-than-two-components
It provides two notable examples:
Obviously second example is wrong, because I cannot expect that consumers will be always using two-way binding.
What is the correct pattern for handling component parameters that might change from the inside, react to changes from the outside and allow parnets to set init only values at the same time?
I am working on a tab set component and so far have following code:
Beta Was this translation helpful? Give feedback.
All reactions