I have a number of pages that all need the same address. And address is not only the UI part, but there s a bit of code behind, mainly to call the Azure Map API to get the validated form of the address and location.
So it looks like this:
And the way I have set it up is as follows (I ve eliminated a lot of the inner controls for brevity).
The outer razor file:
<EditForm EditContext="EditContext"
OnValidSubmit="HandleValidSubmitAsync"
OnInvalidSubmit="HandleInvalidSubmitAsync"
Context="EditFormContext">
<ObjectGraphDataAnnotationsValidator />
<CustomValidation @ref="_customValidation" />
<DxFormLayout>
<DxFormLayoutItem Caption="Unique Id:" Field="@nameof(Model.UniqueId)" ColSpanMd="4">
<DxTextBox @bind-Text="@Model.UniqueId"
ReadOnly="@(ModeState != Mode.Create)"
ShowValidationIcon="true" />
</DxFormLayoutItem>
<AddressForm @ref="_addressElement"
ReadOnly="@(ModeState == Mode.Read)"
OnValidated="OnAddressValidated"
ValueChanged="@OnAddressChanged"
Value="@Model.AddressModel">
</AddressForm>
<DxFormLayoutItem Visible="@(ModeState != Mode.Create)" ColSpanMd="4">
<DxCheckBox @bind-Checked="@Model.Enabled"
ReadOnly="@(ModeState == Mode.Read)">Enabled</DxCheckBox>
</DxFormLayoutItem>
<DxFormLayoutItem ColSpanMd="12">
<ValidationSummary />
</DxFormLayoutItem>
<DxFormLayoutItem ColSpanMd="12">
<DxButton Enabled="@SubmitEnabled"
Text="@SubmitButtonText"
SubmitFormOnClick="true"
RenderStyle="@ButtonRenderStyle.Secondary" />
</DxFormLayoutItem>
</DxFormLayout>
</EditForm>
And then AddressForm.razor (DxFormLayout
s can be nested):
<DxFormLayout >
<DxFormLayoutItem Caption="Street Address:" Field="@nameof(Value.StreetNumberAndName)" ColSpanMd="12">
<DxTextBox @bind-Text="@Value!.StreetNumberAndName"
ReadOnly = "@ReadOnly"
ShowValidationIcon="true" />
</DxFormLayoutItem>
</DxFormLayout>
The models are:
public class CampaignPageModel
{
// ...
public AddressFormPageModel AddressModel { get; set; }
// ...
}
public class AddressFormPageModel
{
public string? StreetNumberAndName { get; set; }
// ...
}
So a couple of questions about this:
- Is this a reasonable way to do this?
- For the EditContext and Model in AddressForm.razor.cs, do I need to set EditContext as a
[Parameter]
in AddressForm that is set by the Outer.razor component? And then get Model in the AddressForm from the passed down EditContext? - Should AddressForm even have a Value property in this case? If so, it would be the
EditContext.Model.AddressPageModel
property that was passed down - correct? - If I don t have a Value (or do), ok to have a ValueChanged
EventCallback
? I need this because, if the address is not changed, no need to call the Azure Map API (which causes a pause in the UI).
Update: on reconsideration I think the inner component should have its own Context. And it communicates with the outer component using Value and ValueChanged.
Is there guidance from Microsoft on this?