通过Ajax和模型修正ASP.Net MVC2自定义模板加载 [英] ASP.Net MVC2 Custom Templates Loading via Ajax and Model Updating

查看:105
本文介绍了通过Ajax和模型修正ASP.Net MVC2自定义模板加载的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有其他的对象中有一个集合视图模型。

I have a view model with a collection of other objects in it.

public ParentViewModel
{
    public int Id { get; set; }
    public string Name { get; set; }
    public List<ChildViewModel> Child { get; set; } 
}

public ChildViewModel
{
    public int Id { get; set; }
    public string FirstName { get; set; }
}

在我的观点一个我传递一个ParentViewModel为模型,然后使用

In one of my views I pass in a ParentViewModel as the model, and then use

<%: Html.EditorFor(x => x) %>

这为ID和Name属性显示的格式。

Which display a form for the Id and Name properties.

当用户点击一个按钮,我呼吁通过Ajax动作的局部视图这需要孩子的集合加载:

When the user clicks a button I call an action via Ajax to load in a partial view which takes a collection of Child:

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<IEnumerable<Child>>" %>
<%: Html.EditorFor(x => x) %>

然后使用自定义模板的孩子显示传入每个孩子的一种形式。

which then uses the custom template Child to display a form for each Child passed in.

我遇到的问题是,由儿童自定义模板创建的形式不使用使用的DefaultModelBinder的命名约定。

The problem I'm having is that the form created by the Child custom template does not use the naming conventions used by the DefaultModelBinder.

即字段名(当阿贾克斯加载):

ie the field name is (when loaded by Ajax):

[0].FirstName

来代替:

Child[0].FirstName

所以,在我的控制器编辑操作:

So the Edit action in my controller:

[HttpPost]
public virtual ActionResult Edit(int id, FormCollection formValues)
{
    ParentViewModel parent = new ParentViewModel();
    UpdateModel(parent);

    return View(parent);
}

要重新从提交的形式ParentViewModel不起作用。

to recreate a ParentViewModel from the submitted form does not work.

我不知道什么是最好的方式来完成加载在通过Ajax的自定义模板,然后能够使用的UpdateModel的。

I'm wondering what the best way to accomplish loading in Custom Templates via Ajax and then being able to use UpdateModel is.

推荐答案

几件事情要开始的是,你需要记住的默认ModelBinder的是递归的,它会尝试找出它需要做的......所以相当巧妙。另一件事要记住的是你不需要使用HTML佣工,实际的HTML正常工作还有: - )

Couple of things to start with is that you need to remember the default ModelBinder is recursive and it will try and work out what it needs to do ... so quite clever. The other thing to remember is you don't need to use the html helpers, actual html works fine as well :-)

所以,先用型号,没有什么不同,这里..

So, first with the Model, nothing different here ..

public class ParentViewModel
{
    public int Id { get; set; }
    public string Name { get; set; }
    public List<ChildViewModel> Child { get; set; }
}

public class ChildViewModel
{
    public int Id { get; set; }
    public string FirstName { get; set; }
}

父局部视图 - 这需要的ParentViewModel的实例

Parent partial view - this takes an instance of the ParentViewModel

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<ParentViewModel>" %>

<h2>Parent</h2>
<%: Html.TextBox("parent.Name", Model.Name) %>
<%: Html.Hidden("parent.Id", Model.Id) %>

<% foreach (ChildViewModel childViewModel in Model.Child)
{
    Html.RenderPartial("Child", childViewModel);         
}
%>

儿童局部视图 - 这需要一个的ChildViewModel实例

Child partial view - this takes a single instance of the ChildViewModel

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<ChildViewModel>" %>

<h3>Child</h3>
<%: Html.Hidden("parent.Child.index", Model.Id) %>
<%: Html.Hidden(string.Format("parent.Child[{0}].Id", Model.Id), Model.Id)%>
<%: Html.TextBox(string.Format("parent.Child[{0}].FirstName", Model.Id), Model.FirstName) %>

一些需要注意在这一点上,当指标值是什么是用于工作出唯一的记录在列表中。这并不需要是增量值

Something to note at this point is that the index value is what is used for working out the unique record in the list. This does not need to be incremental value.

那么,你怎么骂呢?那么在指数的动作,这是会显示它需要传递的数据。我已经建立了一些演示数据,并在ViewData字典的索引视图返回了。

So, how do you call this? Well in the Index action which is going to display the data it needs to be passed in. I have setup some demo data and returned it in the ViewData dictionary to the index view.

所以控制器动作......

So controller action ...

public ActionResult Index()
{
    ViewData["Message"] = "Welcome to ASP.NET MVC!";

    ViewData["Parent"] = GetData();

    return View();
}

private ParentViewModel GetData()
{
    var result = new ParentViewModel
                     {
                         Id = 1,
                         Name = "Parent name",
                         Child = new List<ChildViewModel>
                                     {
                                         new ChildViewModel {Id = 2, FirstName = "first child"},
                                         new ChildViewModel {Id = 3, FirstName = "second child"}
                                     }
                     };
    return result;
}

在现实世界中,你会打电话数据服务等。

In the real world you would call a data service etc.

和索引视图的最后内容:

And finally the contents of the Index view:

<form action="<%: Url.Action("Edit") %>" method="post">
    <% if (ViewData["Parent"] != null)  { %>

        <%
            Html.RenderPartial("Parent", ViewData["Parent"]); %>

    <% } %>
    <input type="submit" />
</form>

保存

所以,现在我们有数据显示,我们如何把它放回一个动作?嗯,这是一些东西,默认的模型绑定将在相对复杂的地层为你做简单的数据类型。所以,你可以设置的动作要张贴到的基本格式为:

So now we have the data displayed how do we get it back into an action? Well this is something which the default model binder will do for you on simple data types in relatively complex formations. So you can setup the basic format of the action which you want to post to as:

[HttpPost]
public ActionResult Edit(ParentViewModel parent)
{

}

这会给你与原来的IDS更新的详细信息(从隐藏字段),所以可以根据需要更新/编辑。

This will give you the updated details with the original ids (from the hidden fields) so you can update/edit as required.

通过Ajax的新儿童

您的自定义模板通过AJAX提到你的问题加载,你的意思是如何给用户增加的另一个孩子没有回发的选项?

You mentioned in your question loading in custom templates via ajax, do you mean how to give the user an option of adding in another child without postback?

如果是这样,你做这样的事......

If so, you do something like this ...

添加动作 - 需要将返回一个新的ChildViewModel一个动作

Add action - Need an action which will return a new ChildViewModel

[HttpPost]
public ActionResult Add()
    {
        var result = new ChildViewModel();
        result.Id = 4;
        result.FirstName = "** to update **";
        return View("Child", result);
    }

我已经给它方便的演示目的的ID。

I've given it an id for easy of demo purposes.

然后,您需要调用code的一种方式,所以你需要更新唯一的观点是主索引视图。这将包括javascript来获得这种行为的结果,调用code和目标HTML标记的HTML链接被追加到。另外不要忘了你的引用添加到jQuery的母版页或在视图的顶部。

You then need a way of calling the code, so the only view you need to update is the main Index view. This will include the javascript to get the action result, the link to call the code and a target HTML tag for the html to be appended to. Also don't forget to add your reference to jQuery in the master page or at the top of the view.

索引视图 - 更新

<script type="text/javascript">

   function add() {

        $.ajax(
            {
                type: "POST",
                url: "<%: Url.Action("Add", "Home") %>",
                success: function(result) {
                    $('#newchild').after(result);
                },
                error: function(req, status, error) {

                }
        });
    }

</script>

<form action="<%: Url.Action("Edit") %>" method="post">
    <% if (ViewData["Parent"] != null)  { %>

        <%
            Html.RenderPartial("Parent", ViewData["Parent"]); %>

    <% } %>
    <div id="newchild"></div>

    <br /><br />
    <input type="submit" /> <a href="#" onclick="JavaScript:return add();">add child</a>
</form>

这将调用添加动作,并追加响应时,返回newChild对象DIV上面的提交按钮。

This will call the add action, and append the response when it returns to the newChild div above the submit button.

我希望长期职位是非常有用的。

I hope the long post is useful.

享受: - )

这篇关于通过Ajax和模型修正ASP.Net MVC2自定义模板加载的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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