Как связать динамические сложные объекты, созданные с использованием частичного представления, со свойством коллекции в модели представления - PullRequest
0 голосов
/ 22 апреля 2019

Я не могу связать коллекцию дочерних полных объектов, созданных динамически с использованием свойства частичного представления для модели IEnumerable модели.

Я успешно связал объекты, созданные динамически с использованием частичных представлений, длямодель представления, использующая технику, которую я нашел в этом блоге https://haacked.com/archive/2008/10/23/model-binding-to-a-list.aspx/. Я использовал ту же технику, но не могу связать коллекцию со свойством IEnumerable в модели представления.

[BindRequired]
public class EmployeeViewModel
{
   other properties....
   public IEnumerable<ContactDetailViewModel> EmployeeContact { get; set; }
}

[BindRequired]
public class ContactDetailViewModel
{
   // I use this as my indexer for dynamic elements
   public string RecordId { get; set; } = Guid.NewGuid().ToString();

   public string Telephone { get; set; }

   public string EmailAddress { get; set; }

   public string ContactDescription { get; set; }
}

Я вызываю этот метод действия через ajax, чтобы добавить динамические элементы сведений о контакте, и он возвращает частичное представление в виде html, и он работает нормально.

[Route("[action]", Name = "BlankEmployeeContactDetail"), HttpGet("AddBlankContactDetail")]
public PartialViewResult AddBlankContactDetail()
{
            return PartialView("_ContactInformation", new     ContactDetailViewModel());
}

Начальные сведения о контакте добавляются кmain-view, используя следующую, пожалуйста, пройдите по этой ссылке https://1drv.ms/u/s!AkRSHVUtFlKhuHaxH96Ik4ineATE, чтобы загрузить файлы cshtml основного и частичного просмотра.Также следует отметить, что привязка модели не выполняется для всех других свойств, когда я включаю это частичное представление, но работает, когда я закомментирую его.Я сбит с толку и был бы очень признателен за любую помощь, которую вы можете себе позволить.

<section id="widget-grid" class="">
   <div class="row contactContainer">
     @{ await Html.RenderPartialAsync("_ContactInformation", new ContactDetailViewModel()); }
   </div>
</section>

Это метод действия контроллера, к которому я пытаюсь привязать опубликованные данные:

[Route("[action]"), HttpPost, AllowAnonymous, ValidateAntiForgeryToken]
        public IActionResult Register([FromForm] EmployeeViewModel model, [FromQuery] string returnUrl = null)
{
    if (ModelState.IsValid)
    {

    }

    return View(model);
}

1 Ответ

1 голос
/ 22 апреля 2019

Для привязки входные имена во многом соответствуют определенному соглашению, которое сопоставляется с тем, к чему вы привязываетесь. Хотя это неясно из вашего вопроса, я думаю, что вы пытаетесь в конечном итоге связать с экземпляром EmployeeViewModel, что означает, что для ввода вашей контактной информации потребуются имена вроде: EmployeeContact[0].Telephone, но когда вы передаете экземпляр ContactDetailViewModel наряду с «моделью» частичного представления имена будут просто Telephone, и, что еще хуже, эти одни и те же имена будут повторяться снова и снова, т.е. каждый созданный вами контактный набор полей будет иметь входные данные. названный просто Telephone.

Короче говоря, вам нужен контекст всей модели для генерации правильных входных имен. У вас есть несколько вариантов.

Поскольку вы извлекаете набор полей с помощью AJAX-запроса, можно передать «префикс» для использования вместе с этим запросом. Другими словами, вы можете отслеживать значение индекса, подсчитывая, сколько из этих разделов вы добавили, а затем отправлять вместе с запросом на новый раздел что-то вроде

prefix: 'EmployeeContact[' + (i + 1) + ']',

Тогда, в вашем частичном представлении:

@{ await Html.RenderPartialAsync("_ContactInformation", new ContactDetailViewModel(), new ViewDataDictionary { TemplateInfo = new TemplateInfo { HtmlFieldPrefix = ViewBag.Prefix } } ); }

Это немного глупо, и, честно говоря, вероятно, довольно склонно к ошибкам. Лучшим вариантом будет совершенно другой подход. Вместо того, чтобы перезванивать, чтобы получить частичное представление, определите его только один раз как шаблон:

<script type="text/html" id="ContactInformationTemplate">
    <!-- HTML for contact information inputs -->
</script>

Затем, используя такие библиотеки, как Vue, React, Angular и т. Д., Вы можете установить конструкцию «foreach», привязанную к конкретному массиву JavaScript, который использует этот шаблон для визуализации элементов в этом массиве. Затем добавить новый набор входных данных так же просто, как добавить новый элемент в массив. Вам придется проделать некоторые работы, чтобы настроить входные имена на основе индекса элемента в массиве, но у всех этих клиентских сред есть способы сделать это. Это также будет иметь побочное преимущество: вам не нужно делать AJAX-запрос каждый раз, когда вы хотите добавить новый раздел.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...