mvc detail advanced asp.net-mvc forms master-detail data-entry

asp.net-mvc - advanced - crud master detail mvc



Formulario de entrada de detalles del maestro MVC de ASP.NET (5)

Estoy tratando de implementar un formulario de entrada de pedidos utilizando ASP.NET MVC pero con muchas dificultades. Todas las muestras que encontré están relacionadas con la visualización de formularios de detalles maestros, y ninguna para agregar o editar.

Supongamos que tengo dos tablas: Order y OrderLines que están relacionadas entre sí con una relación uno a muchos. En la vista principal tenía un botón "Nuevo" al hacer clic, debería mostrar una nueva vista de orden compuesta por los campos de orden, una cuadrícula que muestra las líneas de orden y un botón "Guardar" que al hacer clic persistirá todo el orden junto con sus líneas en una base de datos. La cuadrícula debe tener tres botones: "Agregar línea", "Editar línea" y "Eliminar línea". Cuando se hace clic en "Agregar línea", debe mostrarse una nueva vista que permite al usuario agregar la línea a las líneas de la cuadrícula de vista de orden; en esta etapa, la base de datos no se ve afectada. Cuando el usuario hace clic en "Editar línea", se mostrará una vista que le permite al usuario editar la línea seleccionada y, cuando termine, actualice las líneas de cuadrícula de la orden.

Los problemas más difíciles son:

¿Cómo pasar el pedido y su colección de líneas entre la vista de orden y las vistas de línea de orden?

¿Cómo actualizar la vista de orden en función de los cambios en la vista de línea de orden?

¿Y cómo persistir los cambios entre vistas sin la participación de la base de datos?

¿Hay algún ejemplo concreto que muestre cómo implementar esto usando MVC?

Su ayuda y comentarios son apreciados.



A diferencia de WebForms, ASP.NET MVC no intenta ocultar la naturaleza sin estado de HTTP. Para trabajar con un objeto complejo en múltiples formularios, tiene un par de opciones:

  • Guarde el objeto en el servidor con cada cambio para que el objeto actualizado esté disponible usando solo una identificación
  • Use jquery para rellenar el formulario de línea de pedido y guardar detalles en el formulario principal

Por lo general, voy con la opción del lado del cliente, con el formulario principal con campos ocultos para los datos que se editarán en el subformulario. Sin embargo, puede encontrar la opción del lado del servidor más fácil: si realmente no desea involucrar a la base de datos, puede mantener su objeto parcialmente actualizado en la sesión.


Justo en la parte superior de mi cabeza (una especie de vertedero de cerebros) ...

  • Podría tener una parte de la cuadrícula principal del formulario. Esta sería una vista completa cargada desde una acción (ya sea con un número de orden o no dependiendo de cargar uno existente o no).

  • Al hacer clic en un evento (nuevo o editar), esto podría abrir una vista parcial en un estilo de "lightbox". Esto devolvería un objeto json a la forma principal.

  • El objeto json pasado se representaría usando plantillas en la parte inferior de la tabla (para una nueva) o actualizaría un registro existente. Esto también podría guardarse nuevamente en el servidor en la misma llamada ajax. O simplemente actualice el lado del cliente y necesita que el usuario haga clic en un botón para guardar.

  • Se necesitará un indicador de isDirty para que cualquier cambio lo establezca en verdadero y cuando el navegador intente salir o cerrarse, etc. luego puede solicitar al usuario que lo guarde o no.

Espero que esto ayude.

editar

No lo intenté pero podría ser interesante con el aspecto none db de tu pregunta.


Por favor, eche un vistazo a la publicación de mi blog sobre cómo crear un formulario de detalles maestros en asp.net mvc. también contiene un proyecto de demostración que puedes descargar


Paso 1: Crear modelo de vista

public class OrderVM { public string OrderNo { get; set; } public DateTime OrderDate { get; set; } public string Description { get; set; } public List<OrderDetail> OrderDetails {get;set;} }

Paso 2: agrega JavaScript para agregar líneas de orden

<script src="//code.jquery.com/ui/1.11.4/jquery-ui.js"></script>

$(function () { $(''#orderDate'').datepicker({ dateFormat : ''mm-dd-yy'' }); }); $(document).ready(function () { var orderItems = []; //Add button click function $(''#add'').click(function () { //Check validation of order item var isValidItem = true; if ($(''#itemName'').val().trim() == '''') { isValidItem = false; $(''#itemName'').siblings(''span.error'').css(''visibility'', ''visible''); } else { $(''#itemName'').siblings(''span.error'').css(''visibility'', ''hidden''); } if (!($(''#quantity'').val().trim() != '''' &amp;&amp; !isNaN($(''#quantity'').val().trim()))) { isValidItem = false; $(''#quantity'').siblings(''span.error'').css(''visibility'', ''visible''); } else { $(''#quantity'').siblings(''span.error'').css(''visibility'', ''hidden''); } if (!($(''#rate'').val().trim() != '''' &amp;&amp; !isNaN($(''#rate'').val().trim()))) { isValidItem = false; $(''#rate'').siblings(''span.error'').css(''visibility'', ''visible''); } else { $(''#rate'').siblings(''span.error'').css(''visibility'', ''hidden''); } //Add item to list if valid if (isValidItem) { orderItems.push({ ItemName: $(''#itemName'').val().trim(), Quantity: parseInt($(''#quantity'').val().trim()), Rate: parseFloat($(''#rate'').val().trim()), TotalAmount: parseInt($(''#quantity'').val().trim()) * parseFloat($(''#rate'').val().trim()) }); //Clear fields $(''#itemName'').val('''').focus(); $(''#quantity,#rate'').val(''''); } //populate order items GeneratedItemsTable(); }); //Save button click function $(''#submit'').click(function () { //validation of order var isAllValid = true; if (orderItems.length == 0) { $(''#orderItems'').html(''&lt;span style="color:red;"&gt;Please add order items&lt;/span&gt;''); isAllValid = false; } if ($(''#orderNo'').val().trim() == '''') { $(''#orderNo'').siblings(''span.error'').css(''visibility'', ''visible''); isAllValid = false; } else { $(''#orderNo'').siblings(''span.error'').css(''visibility'', ''hidden''); } if ($(''#orderDate'').val().trim() == '''') { $(''#orderDate'').siblings(''span.error'').css(''visibility'', ''visible''); isAllValid = false; } else { $(''#orderDate'').siblings(''span.error'').css(''visibility'', ''hidden''); } //Save if valid if (isAllValid) { var data = { OrderNo: $(''#orderNo'').val().trim(), OrderDate: $(''#orderDate'').val().trim(), //Sorry forgot to add Description Field Description : $(''#description'').val().trim(), OrderDetails : orderItems } $(this).val(''Please wait...''); $.ajax({ url: ''/Home/SaveOrder'', type: "POST", data: JSON.stringify(data), dataType: "JSON", contentType: "application/json", success: function (d) { //check is successfully save to database if (d.status == true) { //will send status from server side alert(''Successfully done.''); //clear form orderItems = []; $(''#orderNo'').val(''''); $(''#orderDate'').val(''''); $(''#orderItems'').empty(); } else { alert(''Failed''); } $(''#submit'').val(''Save''); }, error: function () { alert(''Error. Please try again.''); $(''#submit'').val(''Save''); } }); } }); //function for show added items in table function GeneratedItemsTable() { if (orderItems.length &gt; 0) { var $table = $(''&lt;table/&gt;''); $table.append(''&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Item&lt;/th&gt;&lt;th&gt;Quantity&lt;/th&gt;&lt;th&gt;Rate&lt;/th&gt;&lt;th&gt;Total&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;''); var $tbody = $(''&lt;tbody/&gt;''); $.each(orderItems, function (i, val) { var $row = $(''&lt;tr/&gt;''); $row.append($(''&lt;td/&gt;'').html(val.ItemName)); $row.append($(''&lt;td/&gt;'').html(val.Quantity)); $row.append($(''&lt;td/&gt;'').html(val.Rate)); $row.append($(''&lt;td/&gt;'').html(val.TotalAmount)); $tbody.append($row); }); $table.append($tbody); $(''#orderItems'').html($table); } } }); </script>

Paso 3: crea una acción para guardar datos

[HttpPost] public JsonResult SaveOrder(OrderVM O) { bool status = false; if (ModelState.IsValid) { using (MyDatabaseEntities dc = new MyDatabaseEntities()) { Order order = new Order { OrderNo = O.OrderNo, OrderDate = O.OrderDate, Description = O.Description }; foreach (var i in O.OrderDetails) { // // i.TotalAmount = order.OrderDetails.Add(i); } dc.Orders.Add(order); dc.SaveChanges(); status = true; } } else { status = false; } return new JsonResult { Data = new { status = status} }; }

puedes descargar el código fuente y el video tutorial