简体   繁体   中英

Updates by partialview not affected to model

I have a problem with updating ViewModel by PartialView. PartialView includes Devices along with the location that varies depending on the DropDownList selected by the Customer . (At the bottom I present sample screenshot). The problem is that after accepting the submit button the property Devices in the ViewModel(FiscalizationViewModel) is not updating. Here are examples of models. I'm not sure I'm trying to solve this problem properly.

namespace TestMVC.ViewModels
{
    public class FiscalizationViewModel
    {
        public int CustomerId { get; set; }
        public string FiscalizationDate { get; set; }

        public List<DevicesToFiscalizationViewModel> Devices { get; set; }

        public FiscalizationViewModel()
        {
            Devices = new List<DevicesToFiscalizationViewModel>();
        }

        public IEnumerable<DevicesToLocalization> GetSelectedIds()
        {
            return (from d in Devices where d.Selected select new DevicesToLocalization() { DeviceId = d.DeviceId, LocalizationId = d.LocalizationId }).ToList();
        }
    }

    public class DevicesToFiscalizationViewModel
    {
        public int DeviceId { get; set; }

        public string DeviceName { get; set; }
        public bool Selected { get; set; }
        public string SerialNumber { get; set; }

        public int LocalizationId { get; set; }
        public IEnumerable<Localization> Localizations { get; set; }

        public DevicesToFiscalizationViewModel()
        {
            Localizations = new List<Localization>();
        }
    }

}

Here is the method that is called by the Customer DropDownList event

public PartialViewResult CustomerChanged(int CustomerId)
{
    var localizations = db.Localizations.Where(i => i.CustomerId == CustomerId).ToList();

    var devicesToFsc = (from d in db.Devices
                        select new DevicesToFiscalizationViewModel()
                            {
                                DeviceId = d.DeviceId,
                                DeviceName = d.Name,
                                SerialNumber = d.SerialNumber,
                            }).ToList();
    foreach (var item in devicesToFsc)
    {
        item.Localizations = localizations;
    }

    return PartialView("~/Views/Fiscalizations/EditorTemplates/DevicesToFiscalizationViewModel.cshtml", devicesToFsc);

//--------------------------------
    $("#customerChanged").on("change", function () {
        $.ajax(
        {
            url: '/Fiscalizations/CustomerChanged?CustomerId=' + $(this).val(),
            type: 'GET',
            data: "",
            contentType: 'application/json; charset=utf-8',
            success: function (data) {
                $("#devicesToFiscalization").html(data);
            }
        });
    });

This is little partial of Views (Fiscalization create view)

    @model TestMVC.ViewModels.FiscalizationViewModel
    <table class="table" id="devicesToFiscalization">
        <thead>
            ...
        </thead>
              @Html.Partial("~/Views/Fiscalizations/EditorTemplates/DevicesToFiscalizationViewModel.cshtml", Model.Devices)
    </table>

PartialView:

@model IEnumerable<TestMVC.ViewModels.DevicesToFiscalizationViewModel>
@foreach(var item in Model)
{ 
<tbody>
   <tr>
       <td style="text-align:center">
        <div class="checkbox">
            @Html.EditorFor(m => item.Selected)
        </div>
    </td>
    <td>
        @Html.DisplayFor(m => item.DeviceName)
    </td>
    <td>
        @Html.DisplayFor(m => item.SerialNumber)
    </td>
    <td>
        @Html.DropDownList("LocalizationId", new SelectList(item.Localizations, "LocalizationId", "Name"), "Select", htmlAttributes: new { @class = "form-control", style = "width: 200px;" })
    </td>
    <td>
        @Html.HiddenFor(m => item.DeviceId)
    </td>
  </tr>
</tbody>

Here is a screenshot of how it looks click and here is screenshot from debugger with bad result bad

Based on my understating from your views, your issues is using different models for main view and partial view. You should use exactly the same model in both the model binding could update the model on server side. keep both models TestMVC.ViewModels.FiscalizationViewModel or IEnumerable<TestMVC.ViewModels.DevicesToFiscalizationViewModel>

It works :) Below I show how it looks after changes

main view:

@model TestMVC.ViewModels.FiscalizationViewModel
    <div id="devicesToFiscalization">
        @Html.Partial("~/Views/Fiscalizations/EditorTemplates/DevicesToFiscalizationViewModel.cshtml", Model)
    </div>

Partial view:

@model TestMVC.ViewModels.FiscalizationViewModel
<table class="table">
<thead>
    <tr>
        <th>
            Select
        </th>
        <th>
            Name
        </th>
        <th>
            Serial number
        </th>
        <th>
            Localization
        </th>
    </tr>
</thead>
<tbody>
    @for (int i = 0; i < Model.Devices.Count; i++)
    {
        <tr>
            <td style="text-align:center">
                <div class="checkbox">
                    @Html.EditorFor(m => m.Devices[i].Selected)
                </div>
            </td>
            <td>
                @Html.DisplayFor(m => m.Devices[i].DeviceName)
            </td>
            <td>
                @Html.DisplayFor(m => m.Devices[i].SerialNumber)
            </td>
            <td>
                @Html.DropDownListFor(m => m.Devices[i].LocalizationId, new SelectList(Model.Devices[i].Localizations, "LocalizationId", "Name"), "Select", htmlAttributes: new { @class = "form-control", style = "width: 200px;" })
            </td>
            <td>
                @Html.HiddenFor(m => m.Devices[i].DeviceId)
            </td>
        </tr>
    }
</tbody>

and CustomerChanged method:

    public PartialViewResult CustomerChanged(int CustomerId)
    {
        var localizations = db.Localizations.Where(i => i.CustomerId == CustomerId).ToList();
        var Devices = (from d in db.Devices
                       select new DevicesToFiscalizationViewModel()
                       {
                           DeviceId = d.DeviceId,
                           DeviceName = d.Name,
                           SerialNumber = d.SerialNumber,
                       }).ToList();

        foreach (var item in Devices)
        {
            item.Localizations = localizations;
        }

        var fsc = new FiscalizationViewModel();
        fsc.Devices = Devices;

        return PartialView("~/Views/Fiscalizations/EditorTemplates/DevicesToFiscalizationViewModel.cshtml", fsc);
    }

========================================================================

I'm trying to write this using EditorFor but I have a problem with correctly writing the CustomerChanged method that returns a list of Devices and not expecting this EditorTemplate that looks as follows:

@model TestMVC.ViewModels.DevicesToFiscalizationViewModel

<tr>
    <td style="text-align:center">
        <div class="checkbox">
            @Html.EditorFor(m => m.Selected)
        </div>
    </td>
    <td>
        @Html.DisplayFor(m => m.DeviceName)
    </td>
    <td>
        @Html.DisplayFor(m => m.SerialNumber)
    </td>
    <td>
        @Html.DropDownListFor(m => m.LocalizationId, new SelectList(Model.Localizations, "LocalizationId", "Name"), "Select", htmlAttributes: new { @class = "form-control", style = "width: 200px;" })
    </td>
    <td>
        @Html.HiddenFor(m => m.DeviceId)
    </td>
</tr>

Main View:

    <table class="table" id="devicesToFiscalization">
         ...
        <tbody>
            @Html.EditorFor(m => m.Devices)
        </tbody>
    </table>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM