MVC обрабатывает индекс элемента коллекции в модели частичного представления

У меня есть ViewModel с коллекцией внутри, например:

public class CreateCampaignViewModel : ControlPanelViewModel
{
    [RequiredField]
    public string Name { get; set; }

    public List<AdvertisementViewModel> Advertisements { get; set; }
    ...
}

в представлении, если я использую его как:

@for (int i = 0; i < Model.Advertisements.Count; i++)
{
  <fieldset style="z-index: 0;">
  <legend>מודעה</legend>
  <table style="width: 100%;">
    <tr>
      <td>
        <label for="@Html.NameFor(m => m.Advertisements[i].Title)">כותרת הפרסומת</label></td>
      <td>@Html.TextBoxFor(m => m.Advertisements[i].Title)</td>
    </tr>
  </table>
  </fieldset>
}

все хорошо, и я вижу список, когда отправляю форму...

но я хочу вложить AdvertisementEditor в частичное представление, поэтому мое представление становится:

@for (int i = 0; i < Model.Advertisements.Count; i++)
{
   Html.RenderPartial("AdvertisementEditor", Model.Advertisements[i]);
}

и мой частичный:

@model Pushed.Models.AdvertisementViewModel

<fieldset style="z-index: 0;">
    <legend>מודעה</legend>
    <table style="width: 100%;">
        <tr>
            <td>
                <label for="@Html.NameFor(m => m.Title)">כותרת הפרסומת</label></td>
                <td>@Html.TextBoxFor(m => m.Title)</td>
        </tr>
    </table>
</fieldset>

Моя проблема в том, что теперь, когда я отправляю форму, я не получаю значения в текстовом поле для каждого объявления.

Это логично, потому что теперь мои теги <input> не имеют имени «advertisement[1].Title», а только «Title», которого нет в моей содержащей модели.

как я могу создать партиал, отражающий один элемент коллекции с его неприличиями, чтобы он правильно размещался в форме?




Ответы (2)


нашел решение, не могу поверить, что не нашел этого раньше!

есть два способа сообщить MVC.NET префикс полей ввода:

  1. создайте EditorTemplate вместо PartialView... и все будет отлично работать.

  2. определить TemplateInfo.HtmlFieldPrefix

вызов частичного представления, как показано на рисунке:

@{ 
  Html.RenderPartial("TargetAudienceParameters", Model.TargetAudienceParameter, 
      new ViewDataDictionary {
           TemplateInfo = new TemplateInfo {
               HtmlFieldPrefix = "Advertisements[4]" // 4 being an example
           } 
      }); 
 }
person Tomer W    schedule 06.02.2014
comment
На самом деле официальный подход к этому заключается в использовании вместо этого EditorTemplate: см. ответ Патрика здесь: stackoverflow.com/a/33397505/71906 - person James McCormack; 08.11.2017

В моем проекте, когда я запускаю эту проблему, я начинаю использовать запрос ajax, который попадает после пользователя вне текстового поля. Это не самое ясное решение, но работает для меня. Также вам необходимо сгенерировать специальный идентификатор в частичном представлении для каждого элемента группы. Что-то о:

function eduFacilityTableSave() {
    $('#eduFacilityTable tr input[type="text"],#eduFacilityTable tr select').change(function () {
        var parId = $(this).parent().parent().attr('id');
        var parentName = parId.replace(/\d+/g, '');
        var parentId = parId.replace(/\D+/g, '');
        var id = $(this).attr('id');
        var text = $(this).val();
        //alert(text);
        $.ajax({
            type: "POST",
            //contentType: "application/json; charset=utf-8",
            url: "/Form/SaveFromForm/",
            data: { id: id, parentId: parentId, parentName: parentName, text: text },
            dataType: "json",
            success: function (data) {
                //
            }
        });
    });
}

public JsonResult SaveFromForm(string id, string parentId, string parentName, string text) {
            if (parentName == "eduFacility") {
                var edufacility = _repository.GetEduFacilityById(Convert.ToInt32(parentId));
                if (id == "EntryYearId") {
                    edufacility.EntryYearId = Convert.ToInt32(text);
                }
                if (id == "FinishYearId") {
                    edufacility.FinishYearId = Convert.ToInt32(text);
                }
                if (id == "FullName") {
                    edufacility.FullName = text;
                }
                if (id == "Speciality") {
                    edufacility.Speciality = text;
                }
                if (ModelState.IsValid) {
                    _repository.UpdateEduFacility(edufacility);
                    _repository.Save();
                }
            }
            return Json("Success", JsonRequestBehavior.AllowGet);
        }
person BorHunter    schedule 06.02.2014