加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > asp.Net > 正文

asp.net-mvc – 使用ViewModel的MVC 3动态表单

发布时间:2020-12-16 00:09:08 所属栏目:asp.Net 来源:网络整理
导读:我已经尝试了几个星期来关注如何创建动态表单的几个教程,使其能够在表单中添加另一个“成分”.这是我试图遵循的文章. http://www.joe-stevens.com/2011/07/24/asp-net-mvc-2-client-side-validation-for-dynamic-fields-added-with-ajax/ 现在我正在使用添加
我已经尝试了几个星期来关注如何创建动态表单的几个教程,使其能够在表单中添加另一个“成分”.这是我试图遵循的文章. http://www.joe-stevens.com/2011/07/24/asp-net-mvc-2-client-side-validation-for-dynamic-fields-added-with-ajax/

现在我正在使用添加链接添加多个recipeIngredients,但是我需要在单击链接时同时添加“ingredientName”和“recipeIngredient”数量.
我的问题是,当我运行应用程序时,recipeingredient的表单有0而不是实际的文本框.当我点击添加新成分时,我可以添加一个文本框,但是当我输入金额并单击保存时,模型数据不会传递给控制器??.

我甚至不知道从哪里开始修复这个,我不确定我是否应该使用viewmodel或者我是否会完全错误.这是我的数据库图http://i44.tinypic.com/xp1tog.jpg.

这是我的CreateView:

@model ViewModels.RecipeViewModel
@using Helpers;



<h2>CreateFullRecipe</h2>

<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>

    <script type="text/javascript">
        $().ready(function () {
            $("#add-recipeingredient").click(function () {
                $.ajax({
                    url: '@Url.Action("GetNewRecipeIngredient")',success: function (data) {
                        $(".new-recipeingredients").append(data);
                        Sys.Mvc.FormContext._Application_Load();
                    }
                });
            });
        });
    </script>

  @using (Html.BeginForm())
  {
          @Html.ValidationSummary(true)
    <fieldset>
        <legend>Recipe</legend>

        <div class="editor-label">
            @Html.LabelFor(model => model.Recipe.RecipeName)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Recipe.RecipeName)
            @Html.ValidationMessageFor(model => model.Recipe.RecipeName)
        </div>
    </fieldset>


        <fieldset>
            <legend>RecipeIngredients</legend>
            <div class="new-recipeingredients">

                @Html.EditorFor(model => model.RecipeIngredients)

            </div>
            <div style="padding: 10px 0px 10px 0px">
                <a id="add-recipeingredient" href="javascript:void(0);">Add another</a>
            </div>
        </fieldset>

        <div>
            <input type="submit" value="CreateFullRecipe" />
        </div>

  }
<div>
    @Html.ActionLink("Back to List","Index")
</div>

我对recipeingredient的editortemplateview:

@model Models.RecipeIngredient
@using Helpers;

@using (Html.BeginAjaxContentValidation("form0"))
    {
        using (Html.BeginCollectionItem("RecipeIngedients"))
        {
    <div style="padding: 5px 0px 5px 0px">
        @Html.LabelFor(model => model.Amount)
        @Html.EditorFor(model => model.Amount)
        @Html.ValidationMessageFor(model => Model.Amount)
    </div>

        }
    }

我的控制器相关方法:

[HttpGet]
    public ActionResult CreateFullRecipe()
    {
        var recipeViewModel = new RecipeViewModel();
        return View(recipeViewModel);
    }

    //
    // POST: /Recipe/Create

    [HttpPost]
    public ActionResult CreateFullRecipe(RecipeViewModel recipeViewModel)
    {
        if (ModelState.IsValid)
        {
            db.Recipes.Add(recipeViewModel.Recipe);
            db.SaveChanges();
            int recipeID = recipeViewModel.Recipe.RecipeID;
            for (int n = 0; n < recipeViewModel.RecipeIngredients.Count(); n++)
            {
                db.Ingredients.Add(recipeViewModel.Ingredients[n]);
                int ingredientID = recipeViewModel.Ingredients[n].IngredientID;

                recipeViewModel.RecipeIngredients[n].RecipeID = recipeID;
                recipeViewModel.RecipeIngredients[n].IngredientID = ingredientID;
                db.RecipeIngredients.Add(recipeViewModel.RecipeIngredients[n]);

                db.SaveChanges();
            }

            return RedirectToAction("Index");
        }

        return View(recipeViewModel);
    }

    public ActionResult GetNewIngredient()
    {
        return PartialView("~/Views/Shared/IngredientEditorRow.cshtml",new Ingredient());
    }

    public ActionResult GetNewRecipeIngredient()
    {
        return PartialView("~/Views/Shared/_RecipeIngredientEditRow.cshtml",new RecipeIngredient());
    }

我的视图模型:

public class RecipeViewModel
    {
        public RecipeViewModel()
        {
            RecipeIngredients = new List<RecipeIngredient>() { new RecipeIngredient() };
            Ingredients = new List<Ingredient>() { new Ingredient() };
            Recipe = new Recipe();
        }

        public Recipe Recipe { get; set; }
        public IList<Ingredient> Ingredients { get; set; }
        public IList<RecipeIngredient> RecipeIngredients { get; set; }
    }
}

如果有任何其他信息需要帮助解决我的问题,请告诉我.这真的让我发疯,所以我期待着能得到任何帮助
谢谢!

我还想提一下,控制器发布方法createfullrecipe是用于预定义的列表,当我不担心给用户添加另一种成分的能力时它起作用,而我只是默认表单有2种成分而我的观点有这注释掉了创建它们的代码.我真正想做的就是让viewmodel将表单数据传递给控制器??,我可以像我的createfullrecipe控制器方法那样处理数据.

@*    @for (int n = 0; n < Model.Ingredients.Count(); n++)
    {
        <div class="editor-label">
            @Html.LabelFor(model => model.Ingredients[n].IngredientName)
        </div>
                <div class="editor-field">
            @Html.EditorFor(model => model.Ingredients[n].IngredientName)
            @Html.ValidationMessageFor(model => model.Ingredients[n].IngredientName)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.RecipeIngredients[n].Amount)
        </div>
                <div class="editor-field">
            @Html.EditorFor(model => model.RecipeIngredients[n].Amount)
            @Html.ValidationMessageFor(model => model.RecipeIngredients[n].Amount)
        </div>
    }*@

这是我的模型类:

public class Recipe
{
    public int RecipeID { get; set; }
    public string RecipeName { get; set; }
    public string Description { get; set; }
    public int? PrepTime { get; set; }
    public int? CookTime { get; set; }
    public string ImageURL { get; set; }

    public virtual IList<RecipeTag> RecipeTags { get; set; }
    public virtual IList<Rating> Ratings { get; set; }
    public virtual IList<RecipeStep> RecipeSteps { get; set; }
    public virtual IList<RecipeIngredient> RecipeIngredients { get; set; }

}

public class RecipeIngredient
{
    public int RecipeIngredientID { get; set; }
    public string IngredientDesc { get; set; }
    public string Amount { get; set; }
    public int RecipeID { get; set; }
    public int? IngredientID { get; set; }

    public virtual Recipe Recipe { get; set; }
    public virtual Ingredient Ingredient { get; set; }
}

public class Ingredient
{

    public int IngredientID { get; set; }
    public string IngredientName { get; set; }

    public virtual ICollection<RecipeIngredient> RecipeIngredients { get; set; }
}

解决方法

您的代码存在很多问题.我更喜欢一步一步地说明一个简化的例子,你可以适应你的需要.

楷模:

public class RecipeViewModel
{
    public Recipe Recipe { get; set; }
    public IList<RecipeIngredient> RecipeIngredients { get; set; }
}

public class Recipe
{
    public string RecipeName { get; set; }
}

public class RecipeIngredient
{
    public int Amount { get; set; }

    [Required]
    public string IngredientDesc { get; set; }
}

控制器:

public class HomeController : Controller
{
    public ActionResult Index()
    {
        var recipeViewModel = new RecipeViewModel();
        return View(recipeViewModel);
    }

    [HttpPost]
    public ActionResult Index(RecipeViewModel recipeViewModel)
    {
        if (!ModelState.IsValid)
        {
            // there wre validation errors => redisplay the view
            return View(recipeViewModel);
        }

        // TODO: the model is valid => you could pass it to your 
        // service layer for processing

        return RedirectToAction("Index");
    }

    public ActionResult GetNewRecipeIngredient()
    {
        return PartialView("~/Views/Shared/EditorTemplates/RecipeIngredient.cshtml",new RecipeIngredient());
    }
}

查看(?/ Views / Home / Index.cshtml):

@model RecipeViewModel

<script src="@Url.Content("~/Scripts/jquery.validate.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.js")" type="text/javascript"></script>
<script type="text/javascript">
    $(function() {
        $('#add-recipeingredient').click(function () {
            $.ajax({
                url: '@Url.Action("GetNewRecipeIngredient")',type: 'POST',success: function (data) {
                    $('.new-recipeingredients').append(data);
                }
            });
            return false;
        });
    });
</script>

@using (Html.BeginForm())
{
    @Html.ValidationSummary(true)

    <div>
        @Html.LabelFor(model => model.Recipe.RecipeName)
        @Html.EditorFor(model => model.Recipe.RecipeName)
        @Html.ValidationMessageFor(model => model.Recipe.RecipeName)
    </div>

    <fieldset>
        <legend>RecipeIngredients</legend>
        <div class="new-recipeingredients">
            @Html.EditorFor(model => model.RecipeIngredients)
        </div>
        <div style="padding: 10px 0px 10px 0px">
            <a id="add-recipeingredient" href="javascript:void(0);">Add another</a>
        </div>
    </fieldset>

    <div>
        <input type="submit" value="CreateFullRecipe" />
    </div>
}

编辑模板(?/ Views / Shared / EditorTemplates / RecipeIngredient.cshtml):

@model RecipeIngredient

@using (Html.BeginCollectionItem("RecipeIngredients"))
{
    <div>
        @Html.LabelFor(model => model.Amount)
        @Html.EditorFor(model => model.Amount)
        @Html.ValidationMessageFor(model => model.Amount)
    </div>

    <div>
        @Html.LabelFor(model => model.IngredientDesc)
        @Html.EditorFor(model => model.IngredientDesc)
        @Html.ValidationMessageFor(model => model.IngredientDesc)
    </div>
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读