Using MVC and JQuery to dynamically & consistently

2019-08-06 01:28发布

问题:

I have a form which can have multiple values in it.

For example:

Please list your dependants.

I have a fieldset containing my three fields

  • First name,
  • Last name,
  • Date of Birth

as well as an Add button.

My add button fires of a jQuery ajax request and upon the success adds a table row into the table

Pseudo Code:

$.ajax({
    url: myUrl,
    data: myData,
    success: function(){
        var row = $("<tr id='...'>");
        row.append("<td>").text(txtFirstName.val());
        row.append("<td>").text(txtLastName.val());
        row.append("<td>").text(dteDateOfBirth.val());
        row.appendTo($("#myDependantsTable"));
    }
    ...
});

This works great. However, now I have my HTML defined in two different places, my javascript and also in my View

IE:

<tr>
    <td>@Model.FirstName</td>
    <td>@Model.LastName</td>
    <td>@Model.DateOfBirth</td>
</tr>

A problem comes into play when I start modifying these, such as, adding a class on the date column, I need to modify the code twice.

Is there anyway around this problem?

I would like:

  • Rows to be added "ajaxy" without a postback
  • Consistent layout where I only need to make a change in one place

回答1:

You could have the controller action that is called with AJAX request to return a partial view containing a row. The same partial you would use when generating your table. So instead of manipulating HTML with javascript, simply append the returned partial to the table:

$.ajax({
    url: myUrl,
    data: { 
        // That's to bind to the view model that the controller
        // action you are invoking with the AJAX request takes
        // as parameter
        firstName: txtFirstName.val(), 
        lastName: txtLastName.val(), 
        dob: dteDateOfBirth.val() 
    }
    success: function(result) {
        $("#myDependantsTable").append(result);
    }
    ...
});

and in your markup:

<table id="myDependantsTable">
    @foreach(var item in Model)
    {
        @Html.Partial("_Row", item)
    }
</table>

Now your controller action will return the same partial:

public ActionResult SomeActionInvokedWithAjax(MyViewModel model)
{
    return PartialView("_Row", model);
}