Плагин jQuery Form ASP.NET MVC 3, обрабатывающий PartialView

Я пишу страницу ASP.NET MVC для добавления продуктов. На странице появится форма с кнопкой «Добавить», а также список товаров. Когда пользователь нажимает «Добавить», я хочу, чтобы новый продукт был добавлен в список, а форма сбрасывалась. Я пытаюсь сделать это с помощью плагина формы jQuery и без использования Ajax.BeginForm и т. д. Я представил список продуктов в частичном представлении.

Класс продукта выглядит следующим образом:

public class Product
{
    public int Id { get; set; }
    public string Description { get; set; }
    public decimal Price { get; set; }
}

Я использую модель представления:

public class ProductViewModel
{
    public ProductViewModel()
    {
    }

    public ProductViewModel(AjaxDataEntryContext db)
    {
        Products = db.Products.ToList();
        NewProduct = new Product();
    }
    public List<Product> Products { get; set;}
    public Product NewProduct { get; set;}
}

Контроллер делает это:

public class ProductController : Controller
{
    private AjaxDataEntryContext db = new AjaxDataEntryContext();

    [HttpGet]
    public ViewResult AjaxForm()
    {
        return View(new ProductViewModel(db));
    }

    [HttpPost]
    public ActionResult AjaxForm(ProductViewModel viewModel)
    {
        db.Products.Add(viewModel.NewProduct);
        db.SaveChanges();
        return PartialView("_ProductList", db.Products.ToList());
    }
}

Мой cshtml выглядит следующим образом:

@model AjaxDataEntry.ViewModels.ProductViewModel
@{
    ViewBag.Title = "Index";
}
@Html.Partial("_ProductList", Model.Products)
@using (Html.BeginForm("AjaxForm", "Product", null, FormMethod.Post, new { id = "myForm1" }))
{
    @Html.ValidationSummary(true)
    <fieldset>
        <legend>Product</legend>
        <div class="editor-label">
            @Html.LabelFor(model => model.NewProduct.Description)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.NewProduct.Description)
            @Html.ValidationMessageFor(model => model.NewProduct.Description)
        </div>
        <div class="editor-label">
            @Html.LabelFor(model => model.NewProduct.Price)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.NewProduct.Price)
            @Html.ValidationMessageFor(model => model.NewProduct.Price)
        </div>
        <p>
            <input type="submit" value="Create" />
        </p>
    </fieldset>
}

<script type="text/javascript">
    $(document).ready(function () {
        var options = {
            target: '#producttable',   // target element(s) to be updated with server response 
            beforeSubmit: showRequest,  // pre-submit callback 
            success:       showResponse,  // post-submit callback 
            replaceTarget: true,
            dataType:  html,        // 'xml', 'script', or 'json' (expected server response type) 
            clearForm: true        // clear all form fields after successful submit 
        };

        // bind form using 'ajaxForm' 
        $('#myForm1').ajaxForm(options);
    });

    // pre-submit callback 
    function showRequest(formData, jqForm, options) {
        var queryString = $.param(formData);
        alert('About to submit: \n\n' + queryString);
        return true;
    }

    // post-submit callback 
    function showResponse(responseText, statusText, xhr, $form) {
        alert('status: ' + statusText + '\n\nresponseText: \n' + responseText +
        '\n\nThe output div should have already been updated with the responseText.');
    }
</script>

И, наконец, партиал _ProductList, как указано на странице выше (и контроллер):

@model IEnumerable<AjaxDataEntry.Models.Product>
<div id="producttable">
    <table>
        <tr>
            <th>
                Description
            </th>
            <th>
                Price
            </th>
            <th>
            </th>
        </tr>
        @foreach (var item in Model)
        {
            <tr>
                <td>
                    @Html.DisplayFor(modelItem => item.Description)
                </td>
                <td>
                    @Html.DisplayFor(modelItem => item.Price)
                </td>
                <td>
                    @Html.ActionLink("Edit", "Edit", new { id = item.Id }) |
                    @Html.ActionLink("Details", "Details", new { id = item.Id }) |
                    @Html.ActionLink("Delete", "Delete", new { id = item.Id })
                </td>
            </tr>
        }
    </table>
</div>

Моя проблема в том, что когда я нажимаю «Добавить», продукт добавляется правильно, я вижу сообщение showRequest, но когда экран обновляется, все, что я вижу, это список, то есть частичный, а не полный вид. Я также не вижу сообщение showResponse.

Кто-нибудь знает, что я делаю неправильно?


person Richard Clarke    schedule 05.03.2013    source источник
comment
Где ваш тег формы? Это просто не часть вашего примера кода или он находится в другом файле?   -  person Nick DeVore    schedule 05.03.2013
comment
В файле .cshtml есть Html.BeginForm.   -  person Richard Clarke    schedule 05.03.2013
comment
Ах, я прокрутил его из поля зрения. Я нашел этот ответ stackoverflow.com/questions/3663111/, похоже, это может решить вашу проблему.   -  person Nick DeVore    schedule 05.03.2013
comment
Я хорошо прочитал этот ответ, но, похоже, он не применяется. Мой пример не работает в первый раз, затем терпит неудачу, он просто не работает в первый раз. Кроме того, элемент, который я заменяю, не включает форму, выполняющую публикацию.   -  person Richard Clarke    schedule 05.03.2013


Ответы (1)


ShowResponse не вызывается, потому что вы отправляете всю страницу, вместо использования Html.BeginForm(... вы должны использовать Ajax.BeginForm(....

person JoelH    schedule 05.03.2013
comment
Нет необходимости использовать Ajax.BeginForm, так как строка $('#myForm1').ajaxForm(options) должна гарантировать, что форма отправляется с помощью ajax. Кроме того, отображается сообщение showRequest. - person Richard Clarke; 06.03.2013
comment
Хорошо, но я не указал showRequest, я указал ShowResponse. По вашему описанию кажется, что showResponse не срабатывает, потому что отправляется вся страница, и именно поэтому вы видите только частичное представление. - person JoelH; 06.03.2013
comment
Я знаю, но тот факт, что ShowRequest работает, показывает, что форма подключилась к плагину формы jquery и запустила запрос ajax. Что мне нужно знать, так это почему ответ просто не заменяет цель (продуктовую таблицу) содержимым частичного представления. Причина не в том, что я использовал Html.BeginForm. - person Richard Clarke; 06.03.2013
comment
Кто-нибудь еще знает, что здесь происходит не так? Думаю, тот же принцип применим и к простой форме поиска. - person Richard Clarke; 07.03.2013
comment
Когда вы нажимаете «Добавить» и экран обновляется до частичного представления, если вы посмотрите на DOM, вы видите свой <script type="text/javascript"> блок кода? - person JoelH; 07.03.2013