2013-06-06 10 views
6

Chciałbym dynamicznie dodawać elementy do listy w moim modelu za pomocą skryptu java. Jak mogę zmusić MVC do powiązania nowego elementu z modelem?Jak dodać elementy do modelu MVC w javascript?

Moje modele:

public class Garage 
{ 
    public string Name{ get; set; } 
    public string Location { get; set; } 
    public IList<Car> Cars{ get; set; } 
} 

public class Car 
{ 
    public string Color{ get; set; } 
    public string Name { get; set; } 
} 

mój pogląd, który używa garażu jako modelu

<% using (Html.BeginForm()) 
{%> 
<div id="cars"> 
     <% 
       foreach (var item in Model.Cars) 
       { 
        Html.RenderPartial("CarView", item); 
       } %> 
</div> 
<% } %> 

A moja CarView który wykorzystuje samochód, jako modelu

<div class="carRow">    

     <%-- Color--%> 
     <%=Html.CustomLabelFor(model => model.Color)%> 
     <%= Html.TextBox(Model.Color) %> 

     <%-- Name--%> 
     <%=Html.CustomLabelFor(model => model.Name)%> 
     <%= Html.TextBox(Model.Name) %> 
</div> 

Dodając nowy samochód, używam wywołania AJAX i dodaje go do html. AJAX używa tej metody w kontrolerze:

public ViewResult NewCar() 
    { 
     return View("CarView"); 
    } 

Mój skrypt java ajax połączeń:

  $('.addCarButton').click(function() { 
      $.ajax({ 
       url: "<%= Url.Action("CreateCars") %>", 
       cache: false, 
       success: function (html) { $("#cars").append(html); } 
      }); 
      return false; 
     }); 

Czyni html ładnie, ale nie dodać samochód do listy samochodów.

Jak można tego dokonać?

+0

Nie będzie konieczne dodawanie obsługi kliknięć javascript. Te cienie są już zapewnione w MVC. – spons

Odpowiedz

9

Możesz rzucić okiem na following article, w którym Steven Sanderson przedstawia krok po kroku samouczek, jak to wdrożyć.

2

Zdaję sobie sprawę, że jest to stara sprawa, ale po wypróbowaniu powyższą sugestię re Steven Sanderson's BeginCollectionItem i wiele innych potencjalnych rozwiązań, nie zaszedłem zbyt daleko (nowe przedmioty nie zostałyby opublikowane). BeginCollectionItem wydawało się teoretycznie fajnym rozwiązaniem, ale nie zawierało nowych elementów i miało nieoczekiwany wpływ na formatowanie elementów listy.

Rozwiązanie okazało się zaskakująco proste i nie wymagało żadnych zewnętrznych bibliotek (poza JQuery). Działa to dla mnie w ASP.NET MVC5.

  1. Utwórz szablon edytora dla elementu wiersza.

ścieżka: Views/Shared/EditorTemplate/NuggetSourceDto.cshtml

@model [namespace].NuggetSourceDto 

@{ 
    ViewBag.Title = "NuggetSourceDto"; 
} 

<li [email protected]> 
    @Html.HiddenFor(t => t.Id) 
    @Html.TextBoxFor(s => s.Url, new { @class = "form-control", autofocus = "autofocus" }) 
    <a role="button" class="glyphicon glyphicon-remove"></a> 
</li> 
  1. Zastosowanie powyższego szablonu (następujące biegnie poprzez zbieranie i generuje kod HTML dla każdej pozycji):

moim zdaniem:

@Html.EditorFor(m => m.NuggetSources); 
  1. Gdy użytkownik kliknie przycisk "dodaj wiersz" ("addSourceBtn" w moim kodzie poniżej), używam ajaxa, aby uzyskać szablon HTML dla html.

MVC metoda kontroler get:

[HttpGet] 
public PartialViewResult AddBlankSourcesRow() 
{ 
    return PartialView("EditorTemplates/NuggetSourceDto", new NuggetSourceDto()); 
} 

js obsługi:

$(document).ready(function() { 
    $('#addSourceBtn').click(function() { 
     var indexOfNewItem = $('#sourceList li').length; 

     $.ajax({ 
      url: '/nugget/AddBlankSourcesRow/', 
      cache: false, 
      success: function (html) { 
       var newItem = $(html); 
       var randId = Math.random() * 10000000; 
       randId = Math.floor(randId); 
       newItem.attr('id', 'newSource__' + randId); 
       newItem.find('input').first().attr({ 
        //name: 'NuggetSources[3].Id' 
        name: 'NuggetSources[' + indexOfNewItem + '].Id', 
        id: 'NuggetSources_' + indexOfNewItem + '__Id', 
        value: randId 
       }); 
       newItem.find('input[id^=Url]').attr({ 
        name: 'NuggetSources[' + indexOfNewItem + '].Url', 
        id: 'NuggetSources_' + indexOfNewItem + '__Url' 
       }); 
       $('#sourceList').append(newItem); 
      } 
     }); 
     return false; 
    }); 
}); 

Fundamentem w tym wszystkim jest, aby upewnić się, że nowo wstawiony element posiada atrybut name dla każdej nieruchomości zawiera nazwę kolekcji i ważny indeks:

 newItem.find('input').first().attr({ 
      //name: 'NuggetSources[3].Id' 
      name: 'NuggetSources[' + indexOfNewItem + '].Id' 
     }); 
     newItem.find('input[id^=Url]').attr({ 
      name: 'NuggetSources[' + indexOfNewItem + '].Url' 
     }); 

Bez tego nowe elementy są ignorowane w kontrolerze MVC.

To rozwiązanie obsługuje tylko dodawanie nowych wierszy. W przypadku usuwania, ponieważ indeksowanie jest ważne, jednym z rozwiązań jest wysłanie żądania usunięcia do serwera, a następnie ponowne załadowanie listy lub po prostu poprawienie istniejących indeksów w js.

Powiązane problemy