Skip to content

How to access parent component from child component. #15651

Closed
@albiberto

Description

@albiberto

I need to do something very similar to what is described in https://blazor.net/docs/components/index.html,
section [Data Binding], subsection [Component Parameters], with the only exception that I need to update the parent component from the child, so I first moved the button to the latter. The implementation is:

ParentComponent

@page "/ParentComponent"

<h1>Parent Component</h1>

<p>ParentYear: @ParentYear</p>

<ChildComponent bind-Year="@ParentYear" />

@functions {
    [Parameter]
    private int ParentYear { get; set; } = 1978;
}

ChildComponent

<h2>Child Component</h2>
<p>Year: @Year</p>

<button class="btn btn-primary" onclick="@ChangeTheYear">Change Year to 1986</button>

@functions {
    [Parameter]
    private int Year { get; set; }

    [Parameter]
    private Action<int> YearChanged { get; set; }

    void ChangeTheYear()
    {
        Year = 1986;
    }
}

But this approach doesn't work. So I tried to bind the event and value directly (see the code below), but it still fails, the only improvement is that now I can see the "I was called" line in the console output.

ParentComponent

@page "/ParentComponent"

<h1>Parent Component</h1>

<p>ParentYear: @ParentYear</p>

<ChildComponent Year="@ParentYear"  YearChanged="@((e) => { Console.WriteLine("I was called"); @ParentYear = e;})"/>

@functions {
    [Parameter]
    private int ParentYear { get; set; } = 1978;
}

ChildComponent

<h2>Child Component</h2>

<p>Year: @Year</p>

<button class="btn btn-primary" onclick="@ChangeTheYear">Change Year to 1986</button>

@functions {
    [Parameter]
    private int Year { get; set; }

    [Parameter]
    private Action<int> YearChanged { get; set; }

    void ChangeTheYear()
    {
        Year = 1986;
        YearChanged(Year);
    }
}

Then I added manualy UI refresh

ParentComponent

@page "/ParentComponent"

<h1>Parent Component</h1>

<p>ParentYear: @ParentYear</p>

<ChildComponent Year="@ParentYear" YearChanged="@((e) =>
                                   {
                                       Console.WriteLine("I was called!");
                                       @ParentYear = e;
                                       StateHasChanged();
                                   })"></ChildComponent>

@functions {
    [Parameter]
    private int ParentYear { get; set; } = 1978;
}

Child Component

<h2>Child Component</h2>

<p>Year: @Year</p>

<button class="btn btn-primary" onclick="@ChangeTheYear">Change Year to 1986</button>

@functions {
    [Parameter]
    private int Year { get; set; }

    [Parameter]
    private Action<int> YearChanged { get; set; }

    void ChangeTheYear()
    {
        Year = 1986;
        YearChanged(Year);
    }
}

The last thing I tried was to add a manual UI refresh via StateHasChanged(), this works, but I don't understand why the forced refresh is necessary, as the bind-{property} syntax should perform a Two-Way binding already. Is this behaviour intended or is it a bug?

Thanks and regards,
Alberto

Metadata

Metadata

Assignees

No one assigned

    Labels

    area-blazorIncludes: Blazor, Razor Components

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions