1

简而言之:是否可以跟踪调用 Ajax.ActionLink 方法的次数?

现在来看看上下文。我有一个简单的模型:

public class Person {
    public string Name { get; set; }
    public List<Address> Addresses { get; set; }
}

public class Address {
    public string City { get; set; }
    public string Country { get; set; }
}

所以,一个人可以有很多地址。在“创建”页面上,我希望用户单击一个按钮,该按钮允许他们动态添加任意数量的地址。

我将此页面用作学习如何动态绑定到列表的参考:http: //haacked.com/archive/2008/10/23/model-binding-toa-list.aspx

以此作为参考,这是我的课程:

家庭控制器:

    //
    // GET: /Home/
    public ActionResult Index() {
        return View();
    }

    [HttpPost]
    public ActionResult Create(Person p) {
        return View(p);
    }

    [OutputCache(NoStore = true, Duration = 0)]
    public ActionResult AjaxAddAddress() {
        TempData["key"] = DateTime.Now.Ticks.GetHashCode();
        return PartialView("~/Views/Shared/EditorTemplates/Address.cshtml", new Address());
    }

索引视图:

@model ModelTest.Models.Person
<div>
    @using (Html.BeginForm("Create", "Home")) {
        <div>Name: @Html.TextBoxFor(m => m.Name)</div>
        <div id="ajaxAddressBox"></div>

        <p>@Ajax.ActionLink("Add Another Address", "AjaxAddAddress", new AjaxOptions {
            UpdateTargetId = "ajaxAddressBox",
            InsertionMode = InsertionMode.InsertAfter,
            HttpMethod = "GET" })</p>

        <input id="btnSubmit" type="submit" value="Create" />
    }
</div>

创建视图(只是为了确认模型绑定好了):

@model ModelTest.Models.Person
<div>
    <p>You entered person: @Model.Name.</p>

    <p>He has @Model.Addresses.Count total addresses.
    @foreach (var c in Model.Addresses) {
        <p>City: @c.City, Country: @c.Country</p>
    }

</div>

地址编辑器模板:

@model  ModelTest.Models.Address
<p><input type="hidden" name="Addresses.Index" value="@TempData["key"]" />
City: @Html.TextBoxFor(x => x.City, new { Name = "Addresses[" + TempData["key"] + "].City" } )
Country: @Html.TextBoxFor(x => x.Country, new { Name = "Addresses[" + TempData["key"] + "].Country" })</p>

它似乎工作正常,所以我希望到目前为止我做得对。我是 MVC 的新手,所以如果有什么完全错误的,请告诉我。

但我需要它做更多的事情。理想情况下,我想为每一行添加一个标签,上面写着“地址#(索引)”。但更重要的是,我需要限制用户只能添加,例如 5 个地址。无论哪种方式,我都想跟踪调用 Ajax.ActionLink 或方法 AjaxAddAddress 的次数。另外,将来我需要一个也需要该限制的编辑页面。因此,如果现有人员有 3 个地址,他们只能再添加 2 个。

有什么建议吗?这看起来很简单,但我不确定如何最好地处理它。如果我使用了隐藏字段,你如何在 Ajax.ActionLink 中传递该值并在我的 AjaxAddAddress 方法中读取它?你能以某种方式制作一个本地客户端变量吗?

我想 Session 变量会起作用,但我总是很紧张,不确定它的寿命或可靠性。

4

1 回答 1

1

在http://blog.stevensanderson.com/2010/01/28/editing-a-variable-length-list-aspnet-mvc-2-style/的帮助下,这是我想出的一种可能的解决方案。

我没有使用 Ajax.ActionLink,而是使用 Html.ActionLink 并自己手动调用 Ajax。这样,我可以让它直接从 Javascript 中获取值。无论我想要什么值,真的:一个expando、jquery.data、一个隐藏字段,任何东西。

所以我的 Ajax.ActionLink 变成:

@Html.ActionLink("Add Another Address", "AjaxAddAddress", null, new { id = "addItem" })

然后,在同一个视图中,我添加了这个脚本:

<script type="text/javascript">
    $("#addItem").click(function () {
        $.ajax({
            url: this.href + "?index=" + $("#ajaxAddressBox").children('div').size(),
            cache: false,
            success: function (html) {
                $("#ajaxAddressBox").append(html);
            }
        });
        return false;
    });
</script>

我手动将一个索引值传递给我的 AjaxAddAddresses 方法,并且我将该索引值基于当前在 ajaxAddressBox 中的 div 子项的总数,或者换句话说,当前添加的地址总数。因此,将来当我构建一个编辑视图时,它最初会填充现有地址,这个函数将从一开始就知道有多少地址。

AjaxAddAddresses 变为:

    [OutputCache(NoStore = true, Duration = 0)]
    public ActionResult AjaxAddAddress(int? index) {
        if (index >= 5) return null;
        TempData["key"] = DateTime.Now.Ticks.GetHashCode();
        TempData["index"] = index + 1;
        return PartialView("~/Views/Shared/EditorTemplates/Address.cshtml", new Address());
    }

因此,如果索引 >= 5,我返回 null 以便用户无法添加更多。(这也可以在脚本块中完成以保存浪费的 Ajax 调用,但至少在服务器端完成时不能被欺骗。)

地址编辑器模板变为:

@model  ModelTest.Models.Address
<div><p><input type="hidden" name="Addresses.Index" value="@TempData["key"]" />
Address #@TempData["index"] --- 
City: @Html.TextBoxFor(x => x.City, new { Name = "Addresses[" + TempData["key"] + "].City" } )
Country: @Html.TextBoxFor(x => x.Country, new { Name = "Addresses[" + TempData["key"] + "].Country" })</p></div>

当然,仍然欢迎其他解决方案。这对我来说仍然感觉不必要的复杂......

-ps,事实证明,在我的 AjaxAddAddress 方法中使用 Session 变量确实有效,但我无法摆脱在某些情况下它可能会失败的感觉。

于 2012-04-23T12:51:32.343 回答