Al utilizar Entity Data Framework, tengo un modelo definido llamado Client
que simplemente contiene una identificación y un nombre. Luego tengo una asociación con otro modelo llamado Appointment
que contiene una identificación y una fecha.ASP.NET MVC Agregar registros secundarios dinámicamente
Para el formulario, deseo permitir a los usuarios crear un nuevo cliente y en la misma forma, agregar citas (antes de que se cree el cliente). Lo tengo parcialmente funcionando (agregando una cita).
en el controlador:
[HttpPost]
public ActionResult Create(Client client)
{
var appointment = new Appointment();
UpdateModel(appointment);
client.Appointments.Add(appointment);
db.AddToClients(client);
db.SaveChanges();
return RedirectToAction("Index");
}
En la vista:
<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()); %>
vista 'parcial':
<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>
Sin embargo, esto no es ideal por varias razones:
- Solo se puede agregar una cita
- Se producirán problemas si hay conflictos de nombres (p. un campo llamado
Comments
tanto enClient
yAppointment
tabla), ya que ninguna fijación previa se realiza en los nombres de los campos, que también impide que más de una cita que se añade así
¿Qué puedo hacer yo para permitir que múltiples citas que se añadirán , es decir, utilizando un botón para representar una vista parcial (probablemente usando AJAX) en la página cuando se hace clic en "nueva cita" para permitir tantas citas como sea posible. También me gustaría que sea una vista compartida que se pueda usar para crear y editar registros, así como para agregar/eliminar citas en el mismo formulario.
actualización
algunos progresos, utilizando un modelo de vista:
public class ClientViewModel
{
public Client Client { get; set; }
public List<Appointment> Appointments { get; set; }
}
controlador:
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();
}
}
Vista (para las citas, no funciona con un bucle foreach
, ya que cada una de las citas están prefijados con Appointment_
en lugar de Appointment[0]_
):
<%= Html.EditorFor(model => Model.Client) %>
<% for (int i = 0; i < Model.Appointments.Count(); i++) { %>
<%= Html.EditorFor(model => Model.Appointments[i])%>
<% } %>
Esto está bien para crear citas para un nuevo cliente, pero ¿qué hay de editarlas, así como agregar nuevas citas sin publicar el formulario? Para agregar, un enlace que muestra un nuevo formulario de cita bajo el existente, con otro enlace para eliminar (ocultar de vista y establecer un valor de campo oculto).
Actualización 2
tengo trabajo, para añadir citas al crear primero un cliente. Sin embargo, no estoy seguro de cómo actualizar las citas existentes (sin simplemente borrarlas todas y volver a agregarlas).
En el regulador:
[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);
}
Vista:
<%= 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++;
}
);
});
El único problema es que el 'cliente' puede no tener sido creado todavía Si puedo prefijar los nombres de campo con 'Cita' y hacerla en matriz (es decir, añadir [] al nombre), ¿no funcionaría eso (usando UpdateModel ("Cita", cita)? Aunque no estoy seguro de cómo configurar eso arriba – SamWM