I welcome you on the Internet, I have an interesting puzzle for you:
Is it possible to link a view to create an object if this object contains a list of other objects using exclusively MVC / partial views?
The person who got everything complicated is like ... let me give you a quick code example, which I mean:
Models: public class ComplexObject { public string title { get; set; } public List<ContainedObject> contents { get; set; } } public class ContainedObject { public string name { get; set; } public string data { get; set; } }
Nice and easy? Ok, so a strongly typed view to create one of them is really simple for the title property:
something like: @Html.TextBoxFor(x => x.title)
but I cannot find a good way to link the "ContainedObjects" list using MVC. The closest I got is to create a strongly typed partial IEnumerable view with a List forest template and include it on the page.
Without adding style, etc. By default, this partial view is as follows:
@model IEnumerable<MVCComplexObjects.Models.ContainedObject> <p> @Html.ActionLink("Create New", "Create") </p> <table> <tr> <th> @Html.DisplayNameFor(model => model.name) </th> <th> @Html.DisplayNameFor(model => model.data) </th> <th></th> </tr> @foreach (var item in Model) { <tr> <td> @Html.DisplayFor(modelItem => item.name) </td> <td> @Html.DisplayFor(modelItem => item.data) </td> <td> @Html.ActionLink("Edit", "Edit", new { /* id=item.PrimaryKey */ }) | @Html.ActionLink("Details", "Details", new { /* id=item.PrimaryKey */ }) | @Html.ActionLink("Delete", "Delete", new { /* id=item.PrimaryKey */ }) </td> </tr> } </table>
But to be honest, I can't figure out how to enable this as related to creating a new ComplexObject. In other words, I can show a list of existing ContainedObjects by tying them like this: @ Html.Partial ("PartialCreate", Model.contents)
But I really want, I think, something like:
@Html.PartialFor("PartialCreate", x => x.contents)
I should note that I did not have too many problems encoding around this with Javascript (I will include this code below), but I would really like to know if there is a way to do this exclusively with MVC. I am a recent converter from WebForms (where I would just replace all my callbacks with AJAX calls anyway), and a lot of things come up in the projects I'm working on.
Anyway, here's how I do it now:
Html -
Name: <input type="text" id="enterName" /> Data: <input type="text" id="enterData" /> <a id="addItem">Add Item</a> <ul id="addedItems"> </ul> <a id="saveAll">Save Complex Object</a>
Javascript -
<script> var contents = []; $(document).ready(function () { $('#addItem').click(function () { var newItem = { name: $('#enterName').val(), data: $('#enterData').val() }; contents.push(newItem); $('#addedItems').html(''); for (var i = 0; i < contents.length; i++) { $('#addedItems').append( "<li>" + contents[i].name + ", " + contents[i].data + "</li>" ); } }); $('#saveAll').click(function () { var toPost = { title: "someTitle", contents: contents }; $.ajax({ url: '/Home/SaveNew', type: 'POST', data: JSON.stringify(toPost), dataType: 'json', contentType: 'application/json; charset=utf-8', success: function (data, textStatus, jqXHR) { alert("win"); }, error: function (objAJAXRequest, strError) { alert("fail"); } }); }); }); </script>
And this is not a scary decision or something else, I just don’t want to make Javascript calls every time I want to save a new object, but I use standard Razr code everywhere. I would like to be consistent enough in all directions.
Does anyone else run into this problem and find a solution?