I've got a problem with one of my razor component libraries.
I've got an abstract base class RazorHtmlComponent
for my components with a parameter property [Parameter] public string InlineClass { get; set; }
which shall be used for css classes to be mapped to the actual component. Then I've got another base class per component containing the component specific properties which is definined like this: abstract class BaseRazorButton: RazorHtmlComponent
My component, in this example RazorButton.razor
inherits from the abstract button base class BaseRazorButton
.
The problem is, when I instantiate a razor button, and I set the property InlineClass
to any value, it stays null within my actual RazorButton
instance.
Here's a minimal code example for better understanding:
Base class:
public abstract class RazorHtmlComponent : ComponentBase, IRazorHtmlComponent
{
[Parameter] public string InlineClass { get; set; }
public DomDefinitionMapper ClassMapper { get; }
...
protected RazorHtmlComponent()
{
ClassMapper = new DomDefinitionMapper(InlineClass);
}
Dom definition mapper:
public class DomDefinitionMapper
{
public List<Func<string>> DefinitionRepository { get; } = new List<Func<string>>();
public DomDefinitionMapper(string definition = "")
{
if (!string.IsNullOrEmpty(definition))
{
DefinitionRepository.Add(() => definition);
}
}
public string GetDefinitions(char separator = default)
=> separator.Equals(default) ?
string.Join(" ", DefinitionRepository.Select(i => i()).Where(i => i != null))
: string.Join($" {separator}", DefinitionRepository.Select(i => i()).Where(i => i != null));
}
Button base class:
public abstract class BaseRazorButton: RazorHtmlComponent
{
...
}
Razor button component:
@inherits BaseRazorButton
<button class="@ClassMapper.GetDefinitions()">
@Text
</button>
Instantiation of a Razor button:
<RazorButton InlineClass="page"
Text="1"/>
When I inspect within in the browse, the class "page" defined within using the InlineClass
parameter is not set. In debug mode, the ClassMapper
DefinitionRepository
does not contain the class.
Am I missing something? I just don't understand why it doesn't work :/
If you call that in the construtor :
[Parameter] public string InlineClass { get; set; }
...
protected RazorHtmlComponent()
{
ClassMapper = new DomDefinitionMapper(InlineClass);
}
The parameter is not yet set. It'll be when OnInitialized
or OnInitializedAsync
is called.
And your RazorHtmlComponent
must derived from ComponentBase
public abstract class RazorHtmlComponent : ComponentBase, IRazorHtmlComponent
{
[Parameter] public string InlineClass { get; set; }
public DomDefinitionMapper ClassMapper { get; }
...
protected override void OnInitialized()
{
ClassMapper = new DomDefinitionMapper(InlineClass);
}