Reputation: 115
I have a simple component like this:
@foreach(book in store) {
<li @click="@SelectBook(@book.id)"> @book.title <li> <!-- book.id throws error -->
}
@code{
[Parameter]
public EventCallback<MouseEventArgs> OnBookSelected { get; set; }
public async Task SelectBuild(MouseEventArgs e)
{
await OnBuildSelected.InvokeAsync(e);
}
}
On the parent side, I call the component as:
<Book @OnBookSelected="OnBuildSelectedHandler"></Book>
@code{
public void OnBuildSelectedHandler(MouseEventArgs e)
{
// assign to variable to display in html
}
}
As you can some, I am using EventCallback
and InvokeAsync
from what I read to do.
If I don't provide an arg SelectBook
I get the event arg in parent, the the event arg e
does not contain the book id, just some windows properties.
How do I get the clicked Book Id from child to parent?
Thanks
Upvotes: 2
Views: 2896
Reputation: 30001
Here's a slightly modified version of @Enet's answer that demonstrates how to use the built in razor bind framework used in the out-of-the-box Blazor input controls.
The modified BookComponent:
<ul>
@foreach (var book in Books)
{
<li class="@this.Selected(book)" @key="book" @onclick="@(() => this.SelectBook(book))"> @book.Title</li>
}
</ul>
@code
{
[Parameter] public Book Value { get; set; }
[Parameter] public EventCallback<Book> ValueChanged { get; set; }
[Parameter, EditorRequired] public List<Book> Books { get; set; }
public async Task SelectBook(Book book)
=> await ValueChanged.InvokeAsync(book);
// If you want to highlight the selected book
private string Selected(Book item)
=> item.ID == this.Value.ID
? "selected"
: string.Empty;
}
And used like this:
@page "/"
<PageTitle>Index</PageTitle>
@if (_selectedBook != null)
{
<div>@_selectedBook.Title </div>
}
<BookComponent Books="books" @bind-Value=this._selectedBook />
@code
{
private List<Book> books = Enumerable.Range(1, 10)
.Select(i => new Book {ID = i, Title = $"Title{i}"}).ToList();
private Book? _selectedBook;
}
Upvotes: 2