Korzystając z Entity Data Framework, mam zdefiniowany model o nazwie Client
, który po prostu zawiera identyfikator i nazwę. Następnie mam powiązanie z innym modelem o nazwie Appointment
zawierającym identyfikator i datę.ASP.NET MVC dynamicznie dodawaj rekordy podrzędne
Dla formularza, chciałbym umożliwić użytkownikom tworzenie nowego klienta i w tym samym formularzu, dodawać terminy (przed utworzeniem klienta). Częściowo działam (dodając jedno spotkanie).
W regulatorze:
[HttpPost]
public ActionResult Create(Client client)
{
var appointment = new Appointment();
UpdateModel(appointment);
client.Appointments.Add(appointment);
db.AddToClients(client);
db.SaveChanges();
return RedirectToAction("Index");
}
W widoku:
<div class="editor-label">
<%= Html.LabelFor(model => model.Name) %>
</div>
<div class="editor-field">
<%= Html.TextBoxFor(model => model.Name) %>
<%= Html.ValidationMessageFor(model => model.Name) %>
</div>
<% Html.RenderPartial("Appointment", new Appointment()); %>
'Partial' Widok:
<div class="editor-label">
<%= Html.LabelFor(model => model.AppointmentDate) %>
</div>
<div class="editor-field">
<%= Html.TextBoxFor(model => model.AppointmentDate) %>
<%= Html.ValidationMessageFor(model => model.AppointmentDate) %>
</div>
Jednak to nie jest idealny dla kilku powodów:
- Tylko jedno spotkanie można dodać
- Problemy pojawią się, jeśli wystąpią konflikty nazw (np. pole o nazwie
Comments
zarównoClient
iAppointment
tabeli), gdyż nie Prefiksacja odbywa się nazwy pól, co zapobiega również więcej niż jedno powołanie dodaje także
Co mogę zrobić, aby umożliwić wielu nominacje do dodania , czyli za pomocą przycisku, aby wyświetlić częściowy widok (przy użyciu AJAX prawdopodobnie) na stronie, gdy kliknięty zostanie "nowy termin", aby umożliwić jak największą liczbę spotkań? Chciałbym również, aby był to widok wspólny, który można wykorzystać zarówno do tworzenia i edytowania rekordów, jak i dodawania/usuwania spotkań w tej samej formie.
Aktualizacja
Pewien postęp, używając ViewModel:
public class ClientViewModel
{
public Client Client { get; set; }
public List<Appointment> Appointments { get; set; }
}
Kontroler:
public ActionResult Create()
{
Client c = new Client();
List<Appointment> appointments = new List<Appointment>();
appointments.Add(new Appointment() { AppointmentDate = DateTime.Now });
appointments.Add(new Appointment() { AppointmentDate = DateTime.Now.AddMonths(1) });
var model = new ClientViewModel
{
Client = c,
Appointments = appointments
};
return View(model);
}
[HttpPost]
public ActionResult Create(ClientViewModel m)
{
try
{
foreach (var appointment in m.Appointments)
{
m.Client.Appointments.Add(appointment);
}
db.AddToClients(m.Client);
db.SaveChanges();
return RedirectToAction("Index");
}
catch
{
return View();
}
}
widoku (na spotkaniach, nie działa z foreach
pętli, jak każdy z terminów są poprzedzone Appointment_
zamiast Appointment[0]_
):
<%= Html.EditorFor(model => Model.Client) %>
<% for (int i = 0; i < Model.Appointments.Count(); i++) { %>
<%= Html.EditorFor(model => Model.Appointments[i])%>
<% } %>
Jest to przydatne do tworzenia spotkań dla nowego klienta, ale co z ich edycją, a także dodawania nowych spotkań bez konieczności zwrotu formularza? Aby dodać, odsyłacz, który pokazuje nowy formularz spotkania pod istniejącym, z innym linkiem do usunięcia (ukryj przed widokiem i ustaw wartość ukrytego pola).
Aktualizacja 2
Got to praca, do dodawania terminów przy pierwszym tworzeniu klienta. Nie jestem jednak pewien, jak zaktualizować istniejące spotkania (nie usuwając wszystkich i dodając ponownie).
W sterowniku:
[HttpPost]
public PartialViewResult AddAppointment(Appointment appointment, int index)
{
List<Appointment> appointments = new List<Appointment>();
for (int i = 0; i < index; i++)
{
appointments.Add(null);
}
appointments.Add(new Appointment() { AppointmentDate = DateTime.Now });
ViewData["index"] = index;
var model = new ClientViewModel
{
Appointments = appointments
};
return PartialView("Appointment", model);
}
Widok:
<%= Html.EditorFor(model => Model.Client) %>
<div id="appointments">
<% for (int i = 0; i < Model.Appointments.Count(); i++) { %>
<%= Html.EditorFor(model => Model.Appointments[i]) %>
<% } %>
</div>
<a href="javascript:;" id="addappointment">Add Appointment</a>
<script type="text/javascript">
var appIndex = <%= Model.Appointments.Count() %>;
$("#addappointment").click(function() {
$.post(
"/Client/AddAppointment",
{"index" : appIndex},
function (result) {
$("#appointments").append(result);
// increase index by 1
appIndex++;
}
);
});
Jedynym problemem jest to, że „klient” może nie mieć został już stworzony. Jeśli mogę poprzedzić nazwy pól słowem "Powołanie" i wprowadzić je w tablicy (tj. Dołączyć [] do nazwy), to czy nie byłoby to dziełem (używając UpdateModel ("Spotkanie", termin)? Chociaż nie wiem jak to ustawić w górę – SamWM