2017-02-02 4 views
1

Есть ли способ связать значение DropDownListFor в контексте списка дочерних моделей?DropDownListFor в контексте списка дочерних моделей не связывает значение

В настоящее время, если у меня есть родительская модель, у которой есть список дочерних моделей, которые зациклированы, DropDownListFor HtmlHelper не свяжет это значение.

Я создал случай на dotnetfiddle объяснить это: https://dotnetfiddle.net/RB4UVc

Это код в скрипку скопировано здесь:

Model.cs

using System; 
using System.Web.Mvc; 
using System.Collections.Generic; 
using System.ComponentModel.DataAnnotations; 

namespace HelloWorldMvcApp 
{ 
    public class Model 
    { 
     public int? SelectedValue { get; set; } 

     public List<Value> Values { get; set; } 

     public IEnumerable<SelectListItem> Fields 
     { 
      get 
      { 
       return new[] 
       { 
        new SelectListItem { Text = "1", Value = "1" }, 
        new SelectListItem { Text = "2", Value = "2" }, 
        new SelectListItem { Text = "3", Value = "3" } 
       }; 
      } 
     } 

     public Model() 
     { 
      Values = new List<Value>(); 
     } 
    } 

    public class Value 
    { 
     public int SelectedValue { get; set; } 

     public string Name { get; set; } 
    } 
} 

HomeController.cs

using System; 
using System.Web.Mvc; 
using System.Collections.Generic; 

namespace HelloWorldMvcApp 
{ 
    public class HomeController : Controller 
    { 
     [HttpGet] 
     public ActionResult Index() 
     { 
      var model = new Model(); 

      model.SelectedValue = 2; 
      model.Values.Add(new Value { SelectedValue = 3, Name = "John Doe" }); 

      return View(model); 
     } 
    } 
} 

Index.cshtml

@model HelloWorldMvcApp.Model 

<h1>Single</h1> 
<p>Value: @Model.SelectedValue</p> 

@Html.DropDownListFor(model => model.SelectedValue, Model.Fields) 

<hr> 

<h1>Collection</h1> 

@foreach(var value in Model.Values) 
{ 
    <p>Value: @value.SelectedValue</p> 

    <p>Name: @Html.TextBoxFor(_ => value.Name)</p> 

    @Html.DropDownListFor(_ => value.SelectedValue, Model.Fields) 
} 

<hr> 

<h1>Indexed Collection</h1> 

@for(var i = 0; i < Model.Values.Count(); i++) 
{ 
    <p>Value: @Model.Values[i].SelectedValue</p> 

    <p>Name: @Html.TextBoxFor(model => model.Values[i].Name)</p> 

    @Html.DropDownListFor(model => model.Values[i].SelectedValue, Model.Fields) 
} 

Первый использует обычное значение, которое связывает правильно, то второй будет коллекция ребенка моделей. Как видим, TextBoxFor способен правильно привязать значение.

Я делаю что-то неправильно здесь или есть обходной путь для этой проблемы? (около здания вручную a <select> элемент)

Сторона примечания: Я смотрю специально для этого в контексте цикла, учитывая, что мне нужно сохранить массив дочерних моделей в партии.

+1

Вам необходимо включить код в свой вопрос (ссылка может погубить, что делает вопрос бесполезным, и он даже не работал, когда я навещал его). Проблема объясняется в [этом ответе] (http://stackoverflow.com/questions/37407811/mvc5-razor-html-dropdownlistfor-set-selected-when-value-is-in-array/37411482#37411482) –

+0

@ StephenMuecke Я редактировал код, скопированный здесь. Преимущество dotnetfiddle заключалось в том, чтобы запустить его с самого начала, но я вижу вашу точку зрения. Кроме того, большой ответ вы нашли там! Это хак-иш, но может работать. – Erick

+1

Может работать? Это так, и мой ответ :). И как примечание, опция 'foreach'loop (в вопросе, а не скрипка) не работает, когда вы отправляете - см. [Этот ответ] (http://stackoverflow.com/questions/30094047/html-table- to-ado-net-datatable/30094943 # 30094943) для объяснения –

ответ

0

Во-первых, вам не нужно вручную увеличивать значение, чтобы получить текущий индекс в вашем цикле сбора. Вы можете написать его как «для» петли вместо «» Еогеасп как так: (. Обратите внимание, я не проверял этот код)

@for(int i = 0; i < Model.Values.Count(); i++) 
{ 
    <p>Value: @Model.Values[i].SelectedValue</p> 

    <p>Name: @Html.TextBoxFor(model => model.Values[i].Name)</p> 

    @Html.DropDownListFor(model => model.Values[i].SelectedValue, Model.Fields) 
} 

Во-вторых, есть «Selected 'boolean в объекте SelectListItem. Попробуйте установить значение true для объекта, который вы хотите выбрать при загрузке страницы.

+0

Учитывая цикл 'for', inded, я знал об этом.Что касается 'DropDownListFor', находится ли он внутри for или foreach, никаких изменений в привязке нет. Кроме того, проблема с SelectedValue заключается в том, что у вас есть подмодели с 30 категориями, у вас есть в общей сложности 900 элементов списка в памяти. это значительно увеличивает объем памяти для такого тривиального использования. Хотя, для небольших обычаев это очень полезно. – Erick

+0

@Erick Извините, я не уверен, понимаю ли я эту проблему; вы говорите, что хотите моделировать привязку фактического набора предметов? – jdurc

+0

вы предлагаете использовать значение «Selected» для SelectListItem. Когда у вас есть несколько выпадающих списков с одним и тем же списком, вы будете привязывать все к одному списку. Следовательно, вы не можете использовать «Выбранные» или вам нужно сбросить это значение перед каждым выпадающим списком. Если вы не сбросите его, другой способ состоит в том, чтобы иметь другую копию для каждого выпадающего списка. Следовательно, если у вас есть 30 выпадающих списков со списком из 30 вариантов, у вас будет в общей сложности 900 объектов SelectListItem в памяти. Это неважно. – Erick

Смежные вопросы