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 を初めて使用するので、何か完全に間違っている場合はお知らせください。

しかし、もっとやる必要があります。理想的には、各行に「Address #(index)」というラベルを追加したいと考えています。しかし、もっと重要なことは、たとえば 5 つのアドレスの追加のみにユーザーを制限する必要があることです。いずれにせよ、Ajax.ActionLink または AjaxAddAddress メソッドが呼び出された回数を追跡したいと思います。さらに、将来的には、その制限も必要とする編集ページが必要になります。したがって、既存の人が 3 つのアドレスを持っている場合、追加できるのは 2 つだけです。

何かアドバイス?それは簡単に思えますが、どのようにアプローチするのが最善かわかりません。隠しフィールドを使用した場合、その値を Ajax.ActionLink に渡し、AjaxAddAddress メソッドで読み取るにはどうすればよいですか? どうにかしてローカル クライアント変数を作成できますか?

セッション変数が機能すると思いますが、それを使用すると、その寿命や信頼性がわからず、いつも緊張します。

4

1 に答える 1

1

http://blog.stevensanderson.com/2010/01/28/editing-a-variable-length-list-aspnet-mvc-2-style/の助けを借りて、私が思いついた解決策の 1 つを次に示します。

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>

Index 値を手動で 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 呼び出しを保存するためにスクリプト ブロックでも実行できますが、少なくともサーバー側で実行すると、なりすましはできません。)

Address Editor テンプレートは次のようになります。

@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 メソッドでセッション変数を使用すると機能しますが、状況によっては失敗する可能性があるという感覚を揺るがすことはできません。

于 2012-04-23T12:51:32.343 に答える