如何从Blazor @code块中的单选/复选框表单提交中获取数据?

时间:2019-10-16 17:35:53

标签: c# asp.net-core blazor blazor-server-side

我正在制作一个使用“问题”组件的测验/考试页面。问题包含带有复选框或单选框和提交按钮的答案。我需要能够将选定的答案与正确的答案(当用户单击“提交” (或某些其他按钮类型)时)进行比较,但是我不确定如何在我的@code块中获取输入值进行处理。

我已经弄乱了@ bind-value,但它似乎根本与单击按钮无关,我只想要一个答案(选定的答案)中的值。

到目前为止,使用“提交”按钮似乎不是正确的方法,因为它会发出POST请求,这不是我要查找的行为。我只希望按钮触发组件中的处理。

这是我的组成部分

<form>
    <div class="q-card">
        <h3>@Question.QuestionText</h3>
        @foreach (var option in Question.Options)
        {
            <div>
                <input type="@Question.InputType" id="@answer" name="@Question.Id" value="@answer"/>
                <label for="@answer">@answer</label>
            </div>
        }
        <div class="q-controls">
            <button type="submit"@onsubmit="@OnSubmit">Submit</button>
        </div>
    </div>
</form>

和我的@code块

@code {
    public string answer;

    public void OnSubmit()
    {
        System.Console.WriteLine(answer);
    }
}

当我单击“提交”时,我希望选择的值以变量answer结尾。我意识到如果有多个答案(复选框),则需要更改此变量,但稍后再讲。

2 个答案:

答案 0 :(得分:1)

这是我想到的用于实现单选按钮组的代码。

<EditForm Model="cleaningModel" OnValidSubmit="Submit">
     <DataAnnotationsValidator />
     <div class="form-group">
        <p class="csCleanedBox">
           Cleaned:
        </p>
        <p class="csLineCondition">
            Line Condition:  <br />
            <input type="radio" id="0" name="Cleaned" value="0" checked="checked" @onclick="(() => { RadioButtonClicked(0); })">
            <label for="0">Not Cleaned</label>
        </p>
        <input type="radio" id="1" name="Cleaned" value="1" @onclick="(() => { RadioButtonClicked(1); })">
        <label for="1">1</label>
        <input type="radio" id="2" name="Cleaned" value="2" @onclick="(() => { RadioButtonClicked(2); })">
        <label for="2">2</label>
        <input type="radio" id="3" name="Cleaned" value="3" @onclick="(() => { RadioButtonClicked(3); })">
        <label for="3">3</label>
        <input type="radio" id="4" name="Cleaned" value="4" @onclick="(() => { RadioButtonClicked(4); })">
        <label for="4">4</label>
        <input type="radio" id="5" name="Cleaned" value="5" @onclick="(() => { RadioButtonClicked(5); })">
        <label for="5">5</label>
    </div>
    <button class="btn btn-danger" type="button" @onclick="@BackButton">Cancel</button>
    <button class="btn btn-primary" type="submit">Submit</button>
    <ValidationSummary />
</EditForm>
@Code
{
  public class CleaningDto
  {
    public int Oid { get; set; }
    public int Cleaned { get; set; }
  }
  private readonly CleaningDto cleaningModel = new CleaningDto();
  public void RadioButtonClicked(int value)
  {
    cleaningModel.Cleaned = value;
  }
  private void Submit()
  {
    dm.Save(cleaningModel);
  }
} 

它的工作方式类似于单选按钮组,并且在用户单击按钮时会更新类。

答案 1 :(得分:0)

@Collin Brittain,了解Blazor不应发回任何邮件。您要查找的行为可用。当您单击按钮时,不会发生回发... Blazor是一个SPA应用程序,在其中只能通过Http调用或SignalR与外界进行通信。但是,我建议您使用Blazor提供的Forms Components。这些组件提供了很多功能,包括验证。

以下工作示例可能会帮助您解决问题:

<form>
        <p>@question</p>

        @foreach (var item in Enum.GetNames(typeof(Question.Colors)))
        {
            <div>
                <input type="radio" name="question1" id="@item" value="@item" @onchange="SelectionChanged" checked=@(selectedAnswer.Equals(item,StringComparison.OrdinalIgnoreCase)) />
                <label for="@item">@item</label>
            </div>
        }
        <div>
            <label>Selected answer is @selectedAnswer</label>
        </div>

        <button type="button" @onclick="@OnSubmit">Submit</button>


    </form>




@code {
    string selectedAnswer = "";
    void SelectionChanged(ChangeEventArgs args)
    {
        selectedAnswer = args.Value.ToString();
    }


    Question question = new Question { QuestionText = "What is the color of the sky" };


    public void OnSubmit()
    { 

          Console.WriteLine(selectedAnswer);

    }

    public class Question
    {

        public string QuestionText { get; set; }
        public enum Colors { Red, Green, Blue, Yellow };

    }
}

回复评论:

此报价来自Blazor团队:

  

当前,默认情况下,我们不对DOM事件调用preventDefault   在大多数情况下。        表单提交事件是一个例外:在这种情况下,如果您具有C#onsubmit处理程序,则几乎可以肯定不想   执行服务器端发布,特别是考虑到它将发生   异步事件处理程序之前。

 Later, it's likely that we'll add a syntax for controlling whether any given event handler triggers a synchronous preventDefault
     

在事件处理程序运行之前。

在下面的代码片段中,表单具有onsubmit处理程序,其结果是,阻止了导航到“关于”页面,您位于表单所在的页面上,并执行了按钮的HandleClick事件处理程序: / p>

<form action="about:blank" @onsubmit=@(() => { })>
    <button id="form-1-button" @onclick=HandleClick>Click me</button>
</form>

但是,此代码段使应用程序导航到“关于”页面。换句话说,表单已提交。此行为意味着使用button元素而不分配type属性等效于使用type =“ submit”

的button。
<form action="about:blank">
    <button id="form-2-button" @onclick="HandleClick">Click me</button>
</form>

为了防止导航到“关于”页面,并执行HandleClick事件处理程序,请为type属性添加值“ button”,如下所示:

<form action="about:blank">
    <button type="button" @onclick="HandleClick" id="form-2-button">Click me</button>
</form>

您问题中的此代码段

<button type="submit"@onsubmit="@OnSubmit">Submit</button>

执行以下操作:提交表单,而不是调用button元素的OnSubmit事件处理程序。

希望这对您有帮助...