MVC Razor View Text in table does not update on ch

2019-07-31 04:44发布

问题:

I am not able to update text in a table row when selecting/deselecting a Checkbox in that row. I want it to change stye from text-decoration:none to text-decoration:line-through

I have a partial view which renders a table like:

|Checkbox|label text|delete link|
|Checkbox|label text|delete link|
|Checkbox|label text|delete link|

I have implemented some JQuery code to update a Bool in the model when the Checkbox is selected/deselected and this appears to work. The model is being updated. I am returning a partial view from the controller and trying to replace the table with the Ajax result

here is my partial view:

<div id="taskList">
    <table>
        @for (int i = 0; i < Model.Tasks.Count; i++)
        {
            <tr id="tableRowTask@(Model.Tasks[i].Id)">
                <td>
                    @Html.CheckBoxFor(m => m.Tasks[i].IsDone, new { data_id=Model.Tasks[i].Id })
                </td>
                <td>
                    @Html.Label(Model.Tasks[i].Title, new { disabled=true, style=Model.Tasks[i].IsDone? "text-decoration:line-through" : "text-decoration:none" })
                </td>
                <td>
                    @Html.ActionLink("Delete", "Delete", new { id = Model.Tasks[i].Id })
                </td>
            </tr>            
        }
    </table>
</div>

here is my javascript:

$("input[type=checkbox]").change(function () {
    var data_id = $(this).data("id");
    var taskListId = '#taskList';
    var tableRowId = '#tableRowTask' + data_id;
    $.ajax({
        url: 'Home/Edit',
        type: 'POST',
        data: { id: data_id, isChecked: $(this).is(':checked') },
        success: function (result) {
            $(taskListId).replaceWith(result);
        }
    });
});

here is are my controller actions:

[HttpGet]
    public ActionResult Index()
    {
        TaskListModel model = new TaskListModel() { Tasks = _db.Tasks.OrderBy(i => i.EntryDateTime).ToList() };
        if (Request.IsAjaxRequest())
        {
            return PartialView("_TaskList", model);
        }
        return View(model);
    }

    // Mark a task as complete
    [HttpPost]
    public ActionResult Edit(int id = 0, bool isChecked = false)
    {
        // database logic
        TaskItem taskItem = _db.Tasks.Find(id);
        if (TryUpdateModel(taskItem))
        {
            taskItem.IsDone = isChecked;
            _db.SaveChanges();
        }

        return RedirectToAction("Index");
    }

Thankyou all for your time!

回答1:

Try Sending Partial View as string and then replace the html result in jquery:

Below is the Controller logic to send partial view as string.

Controller:

[HttpPost]
public JsonResult Edit(int id = 0, bool isChecked = false)
{
    // Your Controller Logic

    return Json((RenderRazorViewToString("PartilaViewName",model), JsonRequestBehavior.AllowGet);
}

    [NonAction]
    public string RenderRazorViewToString(string viewName, object model)
    {
        ViewData.Model = model;
        using (var sw = new StringWriter())
        {
            var viewResult = ViewEngines.Engines.FindPartialView(ControllerContext, viewName);
            var viewContext = new ViewContext(ControllerContext, viewResult.View, ViewData, TempData, sw);
            viewResult.View.Render(viewContext, sw);
            viewResult.ViewEngine.ReleaseView(ControllerContext, viewResult.View);
            return sw.GetStringBuilder().ToString();
        }
    }


回答2:

To get this to work I changed my javascript to:

function onCheckBoxChange() {
    var data_id = $(this).data("id");
    var taskListId = '#taskList';
    var tableRowId = '#tableRowTask' + data_id;
    $.ajax({
        url: 'Home/Edit',
        type: 'POST',
        data: { id: data_id, isChecked: $(this).is(':checked') },
        success: function (result) {
            $(taskListId).replaceWith(result);
            $("input[type=checkbox]").on("change", onCheckBoxChange); // re-attach event handlers
        }
    });
}
$("input[type=checkbox]").on("change", onCheckBoxChange);

now the event handlers are reattached when the contents of the div are replaced and the checkbox change event fires every time it is selected, the model is updated and the label text updates to with its new decoration. BINGO.