Home > Software engineering >  Blazor server side pass an object instance as parameter to nested component
Blazor server side pass an object instance as parameter to nested component

Time:09-29

Here a page, myPage.razor

@page "/myPage"
<div >
    <div >
        <ComponentA />
    </div>
</div>

In the ComponentA I use a ComponentB

<div >
    <div >
        <ComponentB />
    </div>
</div>

In the myPage.razor.cs there is an instance of a class Person. I'd like pass this instance to ComponentA and to ComponentB.

I tried with [Parameter] and [CascadingParameter] without any success.

Is there a way to do this ?

Thanks,

Update 1: The Microsoft sample below works but that's not do what I want (below the child code). Microsoft

@page "/parameter-parent"
<h1>Child component (without attribute values)</h1>
<ParameterChild />
<h1>Child component (with attribute values)</h1>
<ParameterChild Title="Set by Parent"  Body="@(panelBody)" />
@code {
    PanelBody panelBody = new PanelBody() { Text = "Set by parent.", Style = "italic" };
}

//Child
@using Testing.Pages
<div  style="margin-bottom:15px">
    <div >@Title</div>
    <div  style="font-style:@Body.Style">
        @Body.Text
    </div>
</div>

@code {
    [Parameter]
    public string Title { get; set; } = "Set By Child";

    [Parameter]
    public PanelBody Body { get; set; } =
        new()
        {
            Text = "Set by child.",
            Style = "normal"
        };
}

But I have to receive the object (not create a new one), display in an <input type="text"/> be able to change the text. The new value is update in the object in the ParameterParent. I tried the code below but Body is null all the time (the parent is the same then code above), I tried CascadingParameter too

@using Testing.Pages
<div  style="margin-bottom:15px">
    <div >@Title</div>
    <div  >
        @Body.Text
    </div>
</div>

<InputText id="name" @bind-Value="Body.Text" />

@code {
    [Parameter]
    public string Title { get; set; } = "Set By Child";

    [Parameter]
    public PanelBody Body { get; set; }
}

CodePudding user response:

It is rather straightforward:

@page "/myPage"
<div >
    <div >
        <ComponentA Item="myItem" />
    </div>
</div>

@code { ItemType myItem = new(); }

and

<div >
    <div >
        <ComponentB Item="Item" />
    </div>
</div>

@code
{
  [Parameter] public ItemType Item { get; set; }
}

Component B should have exactly the same Parameter as Component A.

CodePudding user response:

You can instantiate your model class in MyPage, and cascade its value down to descendants... Copy and test.

MyPage.razor.cs

using Microsoft.AspNetCore.Components;

 public partial class MyPage
    {
        public Person person;
        protected override void OnInitialized()
        {
            person = new Person {FirstName = "Nancy", LastName = "Dvolio" };
        }
    }

MyPage.razor

<h3>MyPage</h3>

<CascadingValue Value="person" IsFixed="true">
    <ComponentA />
</CascadingValue>

<hr />

@code {
    
}

Note: Component names should have initial capital letter...

ComponentA.razor

<h3>ComponentA</h3>

<div>@Person.FirstName</div>
<div>@Person.LastName</div>
<p></p>
<hr />

<ComponentB/>

@code {
    [CascadingParameter]
    public Person Person { get; set; }

}

ComponentB.razor

<h3>ComponentB</h3>

<div>@Person.FirstName</div>
<div>@Person.LastName</div>


@code {
    [CascadingParameter]
    public Person Person { get; set; }

}

Person.cs

(should be defined at the root of your app, unless you use type parameters)

public class Person
{
    public string FirstName {get; set;}
    public string LastName { get; set; }
}

Usage - Index.razor

@page "/"
<MyPage/>
  • Related