动态MVC单选按钮组中选择答案 [英] Dynamic MVC RadioButton Group Selected Answers

查看:191
本文介绍了动态MVC单选按钮组中选择答案的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的提问和回答一个动态填充列表。

I have a dynamically populated list of questions and answers.

两个问题:


  1. 的问题与解答回发后不显示

  2. 选择的答案是缺少

视图模型

public class RegistrationViewModel : RegisterExternalLoginModel
{
    //...etc...
    public Question Question { get; set; }
    public Answer Answer { get; set; }
    public List<Question> Questions { get; set; }
    public IList<Answer> PossibleAnswers { get; set; }
    public List<SelectedAnswer> SelectedAnswers { get; set; }
    public IList<SelectedAnswer> PreviousAnswers 
    { 
        set 
        { 
            foreach(Question q in Questions)
            {
                q.SelectedAnswers = value.Where(t => t.questionId == q.objectId).ToList() ;
            }
        } 
    }
}

选择答案

 public Answer SelectedAnswer 
    { 
        get 
        {
            if (SelectedAnswers != null && SelectedAnswers.Count > 0)
            {
                var answers = SelectedAnswers.Where(t => t.questionId == objectId);
                if (answers.Count() == 1) 
                {
                    var result = Answers.Where(t => t.objectId == answers.First().answerId).First();
                    return result;
                }
            }
            return null;
        } 
    }

的ActionResult

 public ActionResult CreateQuestions()
    {
        RegistrationViewModel vm = new RegistrationViewModel();
        IQFacade facade = new QFacade(CreateUserContext(true));

        //Questions and Answers
        vm.Questions = facade.GetQuestions().ToList();
        vm.PossibleAnswers = facade.GetPossibleAnswers();

        return View(vm);

    }

发表

 [HttpPost]
 public ActionResult CreateQuestions(RegistrationViewModel vm)
    {
        var context = CreateUserContext(true);

            try{
                IQFacade f = new QFacade(context);
                f.CreateSomething(vm.User.name, vm.etc, vm.SelectedAnswers);//Need all the answers here, but null
            }
            catch (Exception ex)
            {
                //error stuff, etc...
                return View(vm);//the questions do not appear after this point. Do I need to bind them again from GetQuestions or shouldn't they still be a part of the vm object that I am returning?
            }
        }

        return RedirectToAction("Index");
    }

在的意见,我使用的是编辑模板

In the views, I am using an Editor Template

 @Html.EditorFor(x => x.Questions)

模板

  @foreach (var possibleAnswer in Model.Answers)
{
    <div class="radio">
        @Html.RadioButtonFor(question => question.SelectedAnswer, possibleAnswer.objectId, new { id = possibleAnswer.objectId })

        <label for="@possibleAnswer.objectId">@possibleAnswer.text <span>@possibleAnswer.value</span></label> <p>@possibleAnswer.description</p>
    </div>
}

一切工作的第一次,但不是回发后。我已经经历了几十相似,所以帖子的阅读。我缺少什么?

Everything works the first time, but not after the postback. I have read through the dozens of similar SO posts. What am I missing?

推荐答案

根据意见,您的模型应该是这样的(不知道你所有的模特属性所以我在这里做一些假设的)

Based on comments, your models should be something like (not sure of all your model properties so I'm making some assumptions here)

public class QuestionVM
{
  public int ID { get; set; } // for binding
  public string Text { get; set; }
  [Required]
  public int? SelectedAnswer { get; set; } // for binding
  public IEnumerable<Answer> PossibleAnswers { get; set; }
}

public class RegistrationViewModel : RegisterExternalLoginModel
{
  public RegistrationViewModel()
  {
    Questions = new List<QuestionVM>();
  }
  //...etc...
  public List<QuestionVM> Questions { get; set; }
}

GET方法

public ActionResult CreateQuestions()
{
    RegistrationViewModel vm = new RegistrationViewModel();
    .....
    // Populate the questions and answers
    var questions = facade.GetQuestions().ToList();
    var answers = facade.GetPossibleAnswers();
    foreach (var question in questions)
    {
      QuestionVM qvm = new QuestionVM();
      qvm.ID = question.ID;
      qvm.Test = question.Text;
      // Add possible answers for the question
      qvm.PossibleAnswers = answers.Where(a => a.QuestionID ==  question.ID);
      // If loading existing questions/answers for existing user, also set value of current SelectedAnswer so its selected by default in the view
      vm.Questions.Add(qvm);
    }
    return View(vm);
}

查看

@model YourAssembly.RegistrationViewModel
....

@for(int i = 0; i < Model.Questions.Count; i++)
{
  @Html.HiddenFor(m > m.Questions[i].ID) // for binding
  @Html.DisplayFor(m > m.Questions[i].Text)
  foreach(var answer in Model.Questions[i].PossibleAnswers)
  {
    @Html.RadioButtonFor(m => m.Questions[i].SelectedAnswer, answer.ID, new { id = answer.ID})
    <label for="@answer.ID">answer.Text</label>
  }
}

POST方法

[HttpPost]
public ActionResult CreateQuestions(RegistrationViewModel vm)
{
  if (!ModelState.IsValid)
  {
    // You need to rebuild the question text and possible answers because these are not posted back
    return View(vm);
  }
  // Your model is now populated with the ID of each question and the selected answer which can be saved to the database

请注意,使他们回来后,你可以为这个问题添加隐藏的输入,并回答文本值,但一般其更好的性能在控制器中重装(如果包括正确的数据说明,包括客户端验证,模型应该总是在回发反正有效)

Note you could add hidden inputs for the question and answer text values so they post back, but generally its better performance to reload in your controller (if you include the correct data annotations and include client side validation, the model should always be valid on postback anyway)

这篇关于动态MVC单选按钮组中选择答案的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆