Отправка формы в компоненте Blazor с родительской страницы - PullRequest
0 голосов
/ 03 апреля 2020

У меня есть компонент мастера Blazor, который содержит форму. Элемент управления мастера состоит из 2 компонентов Blazor -

Wizard.razor

<CascadingValue Value="this">    
<div id="@Id">

    <div id="container-fluid">
        @ChildContent
    </div>
</div>
<button class="btn btn-primary btn-lg" type="button"
        disabled="@(ActiveStepIx == 0)" @onclick="GoBack">
    Previous
</button>
<button class="btn btn-primary btn-lg"
        type="@(IsLastStep ? "submit" : "button")" @onclick="GoNext">
    @(IsLastStep ? "Submit" : "Next")
</button>
</CascadingValue>

/// <summary>
/// Wizard Component
/// </summary>
public partial class Wizard
{
    /// <summary>
    /// List of <see cref="WizardStep"/> added to the Wizard
    /// </summary>
    protected internal List<WizardStep> Steps = new List<WizardStep>();

    /// <summary>
    /// The control Id
    /// </summary>
    [Parameter]
    public string Id { get; set; }

    /// <summary>
    /// The ChildContent container for <see cref="WizardStep"/>
    /// </summary>
    [Parameter]
    public RenderFragment ChildContent { get; set; }

    /// <summary>
    /// The Active <see cref="WizardStep"/>
    /// </summary>
    [Parameter]
    public WizardStep ActiveStep { get; set; }

    /// <summary>
    /// The Index number of the <see cref="ActiveStep"/>
    /// </summary>
    [Parameter]
    public int ActiveStepIx { get; set; }

    /// <summary>
    /// Determines whether the Wizard is in the last step
    /// </summary>

    public bool IsLastStep { get; set; }

    /// <summary>
    /// Sets the <see cref="ActiveStep"/> to the previous Index
    /// </summary>

    protected internal void GoBack()
    {
        if (ActiveStepIx > 0)
            SetActive(Steps[ActiveStepIx - 1]);
    }

    /// <summary>
    /// Sets the <see cref="ActiveStep"/> to the next Index
    /// </summary>
    protected internal void GoNext()
    {
        if (ActiveStepIx < Steps.Count - 1)
        {
            SetActive(Steps[(Steps.IndexOf(ActiveStep) + 1)]);
        }                
        else
        {
            // TODO: SUBMIT THE FORM
            Console.WriteLine("FORM SUBMITTED");
        }                
    }

    /// <summary>
    /// Populates the <see cref="ActiveStep"/> the Sets the passed in <see cref="WizardStep"/> instance as the
    /// </summary>
    /// <param name="step">The WizardStep</param>

    protected internal void SetActive(WizardStep step)
    {
        ActiveStep = step ?? throw new ArgumentNullException(nameof(step));

        ActiveStepIx = StepsIndex(step);
        if (ActiveStepIx == Steps.Count - 1)
            IsLastStep = true;
        else
            IsLastStep = false;
    }

    /// <summary>
    /// Retrieves the index of the current <see cref="WizardStep"/> in the Step List
    /// </summary>
    /// <param name="step">The WizardStep</param>
    /// <returns></returns>
    public int StepsIndex(WizardStep step) => StepsIndexInternal(step);
    protected int StepsIndexInternal(WizardStep step)
    {
        if (step == null)
            throw new ArgumentNullException(nameof(step));

        return Steps.IndexOf(step);
    }
    /// <summary>
    /// Adds a <see cref="WizardStep"/> to the WizardSteps list
    /// </summary>
    /// <param name="step"></param>
    protected internal void AddStep(WizardStep step)
    {
        Steps.Add(step);
    }

    protected override void OnAfterRender(bool firstRender)
    {
        if (firstRender)
        {
            SetActive(Steps[0]);
            StateHasChanged();
        }
    }
}

WizardStep.razor

@if (Parent.ActiveStep == this)
{
<div id="step-@(Parent.StepsIndex(this) + 1)">
    @ChildContent
</div>
}

/// <summary>
/// Wizard Step component
/// </summary>
public partial class WizardStep
{
    /// <summary>
    /// The <see cref="Wizard"/> container
    /// </summary>
    [CascadingParameter]
    protected internal Wizard Parent { get; set; }

    /// <summary>
    /// The Child Content of the current <see cref="WizardStep"/>
    /// </summary>
    [Parameter]
    public RenderFragment ChildContent { get; set; }

    /// <summary>
    /// The Name of the step
    /// </summary>
    [Parameter]
    public string Name { get; set; }


    protected override void OnInitialized()
    {
        Parent.AddStep(this);
    }
}

Мастер содержит форму. Я отображаю эту форму в модальном всплывающем окне, и на родительской странице у меня есть метод с именем HandleValidSubmit (), который отправляет форму. Как я могу вызвать этот метод с помощью кнопки «Отправить» на Wizard.razor?

ParentPage.razor

<EditForm Model="@ItemForTradeObject">
<Wizard Id="AddItemWizard">
    <WizardStep Name="Item">
        <div class="form-group  col-md-6">
        <label class="sr-only" for="itemName">Item Name</label>
        <div class="input-group">
        <InputText id="itemName" class="form-control" @bind-Value="@ItemForTradeObject.ItemName" />          <ValidationMessage For="@(() => ItemForTradeObject.ItemName)" />
    </div>
    </WizardStep>
    <WizardStep Name="Costing">
        <div class="form-group  col-md-6">
        <label class="sr-only" for="shippingCost">Cost Price</label>
        <div class="input-group">
            <div class="input-group-addon">£</div>
                <InputText id="costPrice" class="form-control" @bind-Value="@ItemForTradeObject.CostPrice" />
            </div>
            <ValidationMessage For="@(() => ItemForTradeObject.CostPrice)" />
        </div>
    </WizardStep>
</Wizard>

@code {
private async void HandleValidSubmit()
{
    if (ItemForTradeObject.Id == 0)
    {
        // Add
        ItemForTradeObject.UserId = await localStorage.GetItemAsync<string>("userid");

        await Http.PostJsonAsync("api/trading/add", ItemForTradeObject);
    }
    else
    {
        // Update
        ItemForTradeObject.UserId = await localStorage.GetItemAsync<string>("userid");

        await Http.PostJsonAsync("api/trading/update", ItemForTradeObject);
    }

    await CloseTaskModal();
    DataChanged?.Invoke();
}
}

1 Ответ

1 голос
/ 03 апреля 2020

Как я могу вызвать этот метод с помощью кнопки «Отправить» на Wizard.razor?

Вы не вызываете HandleValidSubmit с помощью кнопки «Отправить» на Wizard.razor. Он автоматически вызывается, когда вы нажимаете кнопку «Отправить», и модель действительна.

Выполните следующие действия:

ParentPage.razor

<EditForm Model="@ItemForTradeObject" OnValidSubmit="HandleValidSubmit">
@*.............................................*@
</EditForm>

Wizard.razor

<button class="btn btn-success" type="submit">
    Submit Search
</button>

Надеюсь, это поможет ...

...