简体   繁体   English

将视图模型实例发布回几个动作方法

[英]Post view model instance back to several action methods

I have one ViewModel which has 8 properties and 6 of them are complex types. 我有一个ViewModel ,它有8个属性,其中6个是复杂类型。 And I must display them in 3 groups and to save all data to database at last. 我必须在3组中显示它们,并最终将所有数据保存到数据库中。 Now, I have created two methods for this purpose, the first will be decorated with HttpGet and the second one with HttpPost . 现在,我已经为此创建了两个方法,第一个用HttpGet装饰,第二个用HttpPost装饰。 I have already created all these 3 groups in one .cshtml . 我已经在一个.cshtml创建了所有这三个组。 For the first time, only the first group is visible. 这是第一次只有第一组可见。 And after clicking NEXT button, I will make the second group visible and the first group will be invisible with the help of Javascript/Jquery . 单击“ 下一步”按钮后,我将使第二组可见,并且在Javascript / Jquery的帮助下,第一组将不可见。 And then the third group will be visible. 然后第三组将是可见的。 And in this last part submit button must be appeared. 在最后一部分中,必须出现提交按钮。 After clicking this, I will post whole model back to the action method. 点击这个后,我会将整个模型发布回动作方法。 But, in this scenario I have two problems: 但是,在这种情况下,我有两个问题:

  • I must validate only visible fields with client side validation 我必须通过客户端验证仅验证可见字段
  • If somehow the client side validation passed and the server side is not, then I must find and display not validated part. 如果以某种方式客户端验证通过而服务器端不通过,那么我必须找到并显示未验证的部分。

So, for solving these problems, I have decided two create four action methods, which will post viewmodel back to other one. 因此,为了解决这些问题,我决定创建四个动作方法,将viewmodel发布回另一个。 For making it clear, I want to show this like that: 为了说清楚,我想这样说:

  1. CreateViewModel [HttpGet] CreateViewModel [HttpGet]
  2. GoToSecondPart [HttpPost] GoToSecondPart [HttpPost]
  3. GoToThirdPart [HttpPost] GoToThirdPart [HttpPost]
  4. SaveToDatabase [HttpPost] SaveToDatabase [HttpPost]

1 will return my viewmodel instance to 2, and 2 in his turn will post it to 3, and 3 will post it to 4. 1将我的viewmodel实例返回到2,而2依次将它发布到3,而3将它发布到4。

Is it good aproach? 这是好的方法吗? If not, what would you recommend me? 如果没有,你会推荐我什么?

Your current approach means multiple post/redirects and some form of temporary repository or something that mimics viewstate. 您当前的方法意味着多个帖子/重定向和某种形式的临时存储库或模仿视图状态的东西。 A better approach would be to do everyting within one form and validate individual controls in each section using Validator.element(element) 更好的方法是在一个表单中执行每个操作,并使用Validator.element(element)验证每个部分中的各个控件

In the Next button .click() event 在Next按钮.click()事件中

  1. Select all the the controls within the associated <section> - eg var controls = $(this).closest('section').find('input, textarea, select'); 选择相关<section>所有控件 - 例如var controls = $(this).closest('section').find('input, textarea, select');
  2. In an $.each loop, call $('form').validate().element($(this)); $.each循环中,调用$('form').validate().element($(this));
  3. Test if the controls in the section are valid with $(this).valid(); 测试该部分中的控件是否对$(this).valid();
  4. If everything is valid, hide the current section and display the next 如果一切都有效,请隐藏当前部分并显示下一部分

The final section includes the 'Save'` button which does a normal submit 最后一部分包括“保存”按钮,它可以正常提交

View 视图

<section>
    <h2>Section 1</h2>
    @Html.LabelFor(m => m.SomeProperty)
    @Html.TextBoxFor(m => m.SomeProperty)
    @Html.ValidationMessageFor(m => m.SomeProperty)
    ....
    <div class="error"></div>
    <button type="button" class="next">Next</button>
</section>
<section>
    <h2>Section 2</h2>
    // Your inputs and validation
    <div class="error"></div>
    <button type="button" class="next">Next</button>
<section>
<section>
    <h2>Section 3</h2>
    // Your inputs and validation
    <div class="error"></div>
    <button type="submit" class="next">Submit</button> // submit button for last section
</section>

css (hide all but the first section) css(隐藏除第一部分以外的所有部分)

section:not(:first-of-type) {
    display:none;
}

Script 脚本

$('button').click(function () {
  var container = $(this).closest('section');
  var isValid = true;     
  $.each(container.find('input'), function () { // include select, textarea as required
    $('form').validate().element($(this));
    if (!$(this).valid()) {
      isValid = false;
      return false;
    }
  });
  if (isValid) {
    container.next('.section').show().find('input').first().focus();
    container.hide();
  } else {
    container.find('.error').text('please complete');
  }
});

This will address all client side validation without the need for multiple posts/redirects. 这将解决所有客户端验证,而无需多个帖子/重定向。 As for what happens in the rare instance of having to return the view because the model is still invalid (the error message(s) will be generated but could be in a hidden section so not initially visible) 至于在罕见的必须返回视图的情况下会发生什么,因为模型仍然无效(将生成错误消息,但可能在隐藏的部分中,因此最初不可见)

  1. Just let the user step through the 'wizard' again (may be confusing if an error is not visible in the first section) 让用户再次单步执行“向导”(如果在第一部分中看不到错误,可能会引起混淆)
  2. Use jquery to find the generated error(s), for example $('span.field-validation-error) and the unhide the associated parent section(s) 使用jquery查找生成的错误,例如$('span.field-validation-error)并取消隐藏关联的父节(s)

It sounds to me that you are trying to make a wizard. 听起来你正试图做一个巫师。 It would be easier to break your pages into partials, using the same view model but displaying only the fields that are required for that page (throw the others into hidden fields to save the data). 使用相同的视图模型将页面分成部分更容易,但只显示该页面所需的字段(将其他字段抛出到隐藏字段中以保存数据)。 You could then make AJAX calls back to your controller to render the next / previous pages which will prevent the screen flicker making it look like the page hasn't changed. 然后,您可以将AJAX调用回到控制器以呈现下一个/上一个页面,这将阻止屏幕闪烁,使其看起来像页面未更改。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM