Roland Deschain
Roland Deschain

Reputation: 2830

How to call a function in a parent razor component from a child item in blazor?

I want to create a templated table component following the example in the microsoft documentation.

Here I want to add a sorting function to the table:

// This is a function in the code-behind of TableTemplate.razor
public void SortSourceList(/*some args*/)
{
    // sort based on given args
}

The question is the following. I want this function to be accessible from the children, for example the TableHeader items:

 @page "/somepage
 <TableTemplate Items="pets" Context="pet">
    <TableHeader>
        <th>
             <button class="btn btn-outline-secondary mr-2" 
                 @onclick=<!--call the sorting function from here-->>
        </th>
    </TableHeader>
    <RowTemplate>
        ...
    </RowTemplate>
</TableTemplate>
@code{ // page related code - don't want to handle anything concerning the table here }

I know this could be done by passing down the instance of TableTemplate as a CascadingParameter, but how to get this in a normal html item, which isn't a razor component? Also I don't necessarily want to have to add a TableTemplate instance as class property to any child components (which as far as I know is needed to access a cascading parameter?), so I was wondering if one could pass the function or an event directly?

Upvotes: 2

Views: 1658

Answers (2)

Henk Holterman
Henk Holterman

Reputation: 273179

There is a simple direct way by making the TableHeader typed as well.

Changes in TableTemplate.razor

  <thead>
    <tr>@TableHeader(this)</tr>
  </thead>

@code {
[Parameter]
public RenderFragment<TableTemplate<TItem>>? TableHeader { get; set; }

and then use it like

<TableTemplate Items="pets" >
  <TableHeader Context="table">

       <button @onclick="() => table.SortSourceList(/* args */)" />

  </TableHeader>

  <RowTemplate Context="pet">
     ...
  </RowTemplate>
</TableTemplate>

Upvotes: 3

Francisco Souza
Francisco Souza

Reputation: 47

You can use EventCallback inside the child component and call the parent function:

Parent

<_ChildComponentCall parentFunction="SortSourceList"></_ChildComponent>

public void SortSourceList(/*some args*/)
{
    // sort based on given args
}

Child

<TableTemplate Items="pets" Context="pet">
    <TableHeader>
        <th>
             <button class="btn btn-outline-secondary mr-2" 
                 @onclick="() => parentFunction.InvokeAsync()"
        </th>
    </TableHeader>
    <RowTemplate>
        ...
    </RowTemplate>
</TableTemplate>
@code
[Parameter]
public EventCallback parentFunction { get; set; }

After you run the function you can save the sorting data in a service variable, and call that variable from the child.

Upvotes: 2

Related Questions