2010-10-29 27 views
8

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:

  1. Solo se puede agregar una cita
  2. Se producirán problemas si hay conflictos de nombres (p. un campo llamado Comments tanto en Client y Appointment 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++; 
      } 
     ); 
}); 

Respuesta

1

flotando algunas ideas en torno ..

¿Qué tal si se hace el nombramiento vista parcial contiene un formulario.

Uso jQuery/AJAX para manejar el envío del formulario:

$.post(
    "/SomeController/AddAppointment", 
     appointment, // grab this from the form 
     function (result) { 
      $("#target").html(result); // this will be the div which contains the partial 
     } 
    ); 

que enviaría el establecimiento inflexible cita con el método siguiente acción:

[HttpPost] 
public PartialViewResult AddAppointment(Appointment appointment) 
{ 
    // code to persist entity 
    // code to add errors to model (if necessary) 
    return PartialView("Appointment"); 
} 

Básicamente, su sometimiento la forma usando AJAX, luego volver a presentar el resultado en el parcial. El resultado es similar al AJAX UpdatePanel (de la fama de WebForms).

Así que debe completar los detalles, presionar "enviar", los detalles se publican en el controlador (usando AJAX), luego el formulario estará en blanco de nuevo, para que pueda seguir agregando citas.

¿Eso funcionaría?

+0

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

0

Hay un par de publicaciones en el blog que explica cómo funciona el enlace del modelo con una lista de elementos complejos. Su enfoque de modelo de vista debería funcionar, cuando quiera agregar una nueva cita solo agregue un nuevo elemento a la lista de citas (viewmodel) en el lado del cliente con algún código JS.

Ir a través de estos enlaces que explica cómo la salida de la caja de enlace de modelos MVC funcionaría si rindes el html correctamente

http://www.hanselman.com/blog/ASPNETWireFormatForModelBindingToArraysListsCollectionsDictionaries.aspx

http://haacked.com/archive/2008/10/23/model-binding-to-a-list.aspx

Cuestiones relacionadas