Reputation: 28272
I want to set defaults for parameters on a third-party component. Say I have this:
myBasePage.cs:
public class MyBasePage : ComponentBase
{
public IEnumerable MyData { get; set; }
}
myPage.razor:
@inherits MyBasePage
<ThirdPartyComponent Data="@MyData" />
Since Data
on ThirdPartyComponent
is a [Parameter]
with a DataHasChanged()
virtual method, by rendering the blazor component like that, I'll get one-way binding, and if I change MyData
on my page, programmatically, the component will update. This will work fine.
Now, say I can't modify ThirdPartyComponent
, but I want to make some defaults in it based on my base page... like so:
myPage.razor:
@inherits MyBasePage
<MyDerivedComponent PageComponent="@this" />
myDerivedComponent.cs:
public class MyDerivedComponent : ThirdPartyComponent
{
[Parameter] public MyBasePage PageComponent { get; set; }
public override void OnInitialized()
{
/* Set other parameter defaults */
this.OtherParameter = 10;
/* Bind to Data, as if I was passing it as a parameter in the Razor template */
this.Data = PageComponent.MyData;
}
}
This line:
this.Data = PageComponent.MyData;
Doesn't create a binding at all (and if I modify MyData
, the blazor component doesn't get updated). Is there any way to programmatically create it?
Note: the real ThirdPartyComponent
includes not only tons of parameters but also templates, etc. For many reasons, I'd like MyDerivedComponent
to be of a derived type, and not a "parent component" with a child of ThirdPartyComponent
, if that's possible at all).
Upvotes: 1
Views: 626
Reputation: 30036
Is there any way to programmatically create it? Of course, but that doesn't mean that you should.
Parameters should not be set or manipulated within the component code. Parameters are set externally whenever SetParametersAsync
is called by the Renderer
. If you change them internally you create two versions of the truth.
Upvotes: 1
Reputation: 273179
This should work:
public class MyDerivedComponent : ThirdPartyComponent
{
[Parameter] public MyBasePage PageComponent { get; set; }
public override void OnInitialized()
{
/* Set other parameter defaults */
this.OtherParameter = 10;
//this.Data = PageComponent.MyData;
}
}
protected override void OnParametersSet()
{
Data = Data ?? PageComponent?.MyData ; // determine priority
base.OnParametersSet();
}
OnParametersSet()
notifies the Component that it has new Parameters. The most-derived class can intervene here.
But there is no easy solution for wwhen this.MyData
changes, that's out of sight for Blazor.
Upvotes: 1