2013-11-17 3 views
4

Учитывая модель:MVC5 Добавить элемент в список

public class Receipt: BaseEntity 
{ 
    [Required(AllowEmptyStrings = false,ErrorMessage = "Please Select A Store")] 
    public Store Store { get; set; } 
    public List<Item> Items { get; set; } 
    public Item NewItem { get; private set; } 
    [Required(AllowEmptyStrings = false,ErrorMessage = "ReceiptModel.EntryDate is required")] 
    public DateTime EntryDate { get; set; } 
    public Guid EntryOwner { get; set; } 
    public string Name { get; set; } 

    public double ReceiptTotal() 
    { 
     return Items.Sum(item => item.ItemPrice); 
    } 
    public Receipt() 
    { 
     Items = new List<Item>(); 
     EntryOwner = Guid.Empty; 
     EntryDate = DateTime.Now; 
     Store = new Store(); 
     NewItem = new Item(); 
    }  
} 

и контроллер:

public class ReceiptController : Controller 
{ 
    // 
    // GET: /Receipt/ 

    public ActionResult Index() 
    { 
     Receipt receipt = new Receipt(); 
     return View(receipt); 
    } 

    [HttpPost] 
    public ActionResult AddItem(Receipt receipt) 
    { 
     receipt.Items.Add(receipt.NewItem); 
     if (ModelState.IsValid) 
     { 
      return View("Index", receipt); 
     } 
     return View("Index", receipt); 
    } 

А Вид: Обновлено View - Удалены все частичные страницы и объединены в одну страницу

<form class="form-horizontal" method="POST" action="@Url.Action("AddItem","Receipt")"> 
<div class="jumbotron"> 
    <div id="main" class="panel panel-primary"> 

     <div class="panel-heading"> <h1 class="panel-title">Receipt Builder</h1></div> 
     <div class="panel-body"> 

      <fieldset> 
       @Html.LabelFor(model => model.Name) 
       @Html.EditorFor(model => model.Name) 

       @Html.LabelFor(model => model.Store.Name) 
       @Html.EditorFor(model => model.Store.Name) 

       @Html.LabelFor(model => model.EntryDate) 
       @Html.EditorFor(model => model.EntryDate) 
      </fieldset> 

     </div> 


    </div> 
</div> 

<table class="table table-bordered table-condensed table-hover table-responsive table-striped"> 
    <thead> 
     <tr> 
      <td> 
       <label class="control-label">#</label> 
      </td> 
      <td> 
       <label class="control-label">Item</label> 
      </td> 
      <td> 
       <label class="control-label">Unit</label> 
      </td> 
      <td> 
       <label class="control-label">Quantity</label> 
      </td> 
      <td> 
       <label class="control-label">UnitPrice</label> 
      </td> 
      <td> 
       <label class="control-label">Category</label> 
      </td> 
      <td> 
       <label class="control-label">Total</label> 
      </td> 
     </tr> 
     <tr> 

       <td> 
        <button class="btn-sm btn-danger" style="border-radius: 50%; background-color: red;" name="Submit" id="Submit" type="submit">+</button> 
       </td> 

       <td> 
        @Html.EditorFor(model => model.NewItem.Name) 
       </td> 

       <td> 
        @Html.EditorFor(model => model.NewItem.UnitType) 
       </td> 

       <td> 
        @Html.EditorFor(model => model.NewItem.Quantity) 
       </td> 

       <td> 
        @Html.EditorFor(model => model.NewItem.UnitPrice) 
       </td> 

       <td> 
        @Html.EditorFor(model => model.NewItem.Category.Name)<br/> 
        @Html.EditorFor(model => model.NewItem.Category.IsTaxable) 
       </td> 

       <td> 
        @Html.EditorFor(model => model.NewItem.ItemPrice) 
       </td> 


     </tr> 
    </thead> 
    <tbody> 
     @foreach (var item in Model.Items) 
     { 
      <tr> 
       <td> 
        @Model.Items.ToList().IndexOf(item) + 1 
       </td> 
       <td> 
        @Html.LabelFor(titem => item.Name) 
       </td> 
       <td> 
        @Html.LabelFor(titem => item.UnitType) 
       </td> 
       <td> 
        @Html.LabelFor(titem => item.Quantity) 
       </td> 
       <td> 
        @Html.LabelFor(titem => item.UnitPrice) 
       </td> 
       <td> 
        @Html.LabelFor(titem => item.Category.Name) 
       </td> 
       <td> 
        @Html.LabelFor(titem => item.ItemPrice) 
       </td> 
      </tr> 
     } 
    </tbody> 

    <tfoot></tfoot> 
</table> 

+0

Увидев, что мой ответ не разрешил его: можете ли вы поделиться кодом частичного представления «ItemList»? Я замечаю, что есть и Ajax, можете ли вы поделиться соответствующим кодом? –

+0

@JeroenVannevel Я фактически удалил Ajax-кусок после вашего предложения, так что на странице сейчас только одна форма. Я также добавил запрашиваемые/применимые частичные просмотры – Wjdavis5

+0

Просто подумайте: попробуйте также создать собственное поколение 'newItem' в отдельном частичном представлении. Поскольку это прямо сейчас, возможно, он не сможет привязать поля ввода к фактическому объекту 'newItem', так как это всего лишь поле внутри текущей модели. Вы можете вызвать его с помощью '@ Html.Partial (" _ addItem ", new Item())'. Могли бы вы, возможно, расширить свои точные шаги по определению ошибки, если это не сработает? –

ответ

6

я, наконец, смог решить эту проблему благодаря This Link

Это был действительно связыванию вопрос, как это было предложено. Похоже, что со сложными коллекциями, такими как Списки, мы не можем фактически использовать преимущества IEnumerable, как я надеялся. Это связано с тем, как данные фактически передаются в сообщении с именами, которые неоднозначны. Вот окончательный код, который работает (только для обновления вида)

@for (int i = 0; i < Model.Items.Count(); i++) 
     { 
      <tr> 
       <td> 
       @(i+1) 
       </td> 
       <td> 
        @Html.TextBoxFor(m => m.Items[i].Name) 
       </td> 
       <td> 
        @Html.TextBoxFor(m => m.Items[i].UnitType) 
       </td> 
       <td> 
        @Html.TextBoxFor(m => m.Items[i].Quantity) 
       </td> 
       <td> 
        @Html.TextBoxFor(m => m.Items[i].UnitPrice) 
       </td> 
       <td> 
        @Html.TextBoxFor(m => m.Items[i].Category.Name) 
       </td> 
       <td> 
        @Model.Items[i].ItemPrice 
       </td> 
      </tr> 
     } 

Результирующих имен HTML каждого элемента с индексом т п [N] .Name Теперь почтовые данные может быть связан правильно.

1

Элементы из вашей квитанции отображаются как текст, без элементов управления. Поэтому, когда вы отправляете данные обратно на сервер ASP.NET MVC, эта информация не может быть найдена из тела запроса и оставлена ​​в коллекции Receipt.Items.

Вы можете добавить информацию о введенных квитанциях как скрытые поля на частичном изображении с помощью метода Html.HiddenFor(). Или просто сохраните введенные элементы в БД или в другом месте и прочитайте их в коллекции Receipt.Items, прежде чем возвращать представление AddItem.

+0

Я не уверен, что вы имеете в виду. Свойство NewItem передается со всеми правильными значениями, но свойство List все время передается как пустое. – Wjdavis5

+1

Да, ты прав. Значение свойства NewItem составлено из редакторов, которые вы добавили с помощью методов Html.EditorFor. Но для коллекции Items в вашей форме нет данных, поэтому после отправки данных обратно на сервер эта коллекция пуста. Давайте сделаем небольшой образец. Просто замените вызовы Html.EditorFor в вашем построителе получателей, помеченные Html.LabelFor, добавьте некоторые данные по умолчанию в действие «Квитанция в индекс» и посмотрите результат после отправки формы назад. Данные о получении также будут пустыми после обратной передачи. –

+0

Ваш ответ в конечном итоге привел меня по пути, в котором я должен был пойти, спасибо. – Wjdavis5

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