2013-06-06 3 views
6

Ich möchte Elemente zu einer Liste in meinem Modell dynamisch mit Java-Skript hinzufügen. Wie kann ich MVC veranlassen, den neuen Artikel an das Modell zu binden?Wie Elemente zu MVC-Modell in Javascript hinzufügen?

Meine Modelle:

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; } 
} 

Meine Ansicht, die eine Garage als Modell verwendet:

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

Und mein Carview, die ein Auto als Modell verwendet:

<div class="carRow">    

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

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

Beim Hinzufügen ein neues Auto, ich benutze einen AJAX-Anruf und fügt es dem HTML hinzu. Die AJAX verwendet diese Methode in der Steuerung:

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

Mein Java Script Ajax-Aufruf:

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

Das die HTML schön macht, aber es funktioniert nicht mit dem Auto in der Liste der Autos hinzuzufügen.

Wie kann das gemacht werden?

+0

Es sollte kein JavaScript-Klick-Handler hinzugefügt werden. Diese Thins sind bereits in MVC zur Verfügung gestellt. – spons

Antwort

9

Sie können einen Blick auf die following article werfen, in der Steven Sanderson eine Schritt-für-Schritt-Anleitung zur Implementierung bereitstellt.

2

Ich weiß, dass dies eine alte Frage, aber nach dem obigen Vorschlag re Steven Sanderson's BeginCollectionItem versuchen, und eine Reihe von anderen möglichen Lösungen, kam ich nicht sehr weit (neue Artikel würden nicht posten). BeginCollectionItem schien in der Theorie eine nette Lösung zu sein, aber es würde keine neuen Einträge bereitstellen, und es hatte unerwartete Auswirkungen auf die Formatierung der Listenelemente.

Die Lösung war überraschend einfach und benötigte keine externen Bibliotheken (über JQuery hinaus). Das funktioniert für mich in ASP.NET MVC5.

  1. Erstellen Sie eine Editorvorlage für das Zeilenelement.

Pfad: 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. Verwenden Sie die obige Vorlage (die folgenden Läufe durch die Sammlung und erzeugt HTML-Code für jedes Element):

Aus meiner Sicht:

@Html.EditorFor(m => m.NuggetSources); 
  1. Wenn ein Benutzer auf die Schaltfläche "Zeile hinzufügen" klickt ("addSourceBtn" in meinem Code unten), verwende ich Ajax, um den HTML-Code für die Vorlage zu erhalten.

MVC Controller GET-Methode:

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

js handler:

$(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; 
    }); 
}); 

Die lynchpin dies in allen, dass das neu eingefügte Element ein Namensattribut für jede Eigenschaft hat, um sicherzustellen, Dazu gehören der Name der Sammlung und ein gültiger Index:

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

Ohne dies werden die neuen Elemente im MVC-Controller ignoriert.

Diese Lösung behandelt nur das Hinzufügen neuer Zeilen. Da die Indexierung wichtig ist, besteht eine Lösung darin, eine Löschanforderung an den Server auszulösen und dann die Liste neu zu laden oder einfach die vorhandenen Indizes in js zu fixieren.

Verwandte Themen