126 votes

Une vue partielle sur ASP.NET MVC : entrée des préfixes

Supposons que j'ai ViewModel comme

public class AnotherViewModel
{
   public string Name { get; set; }
}
public class MyViewModel
{
   public string Name { get; set; }
   public AnotherViewModel Child { get; set; }
   public AnotherViewModel Child2 { get; set; }
}

Dans la vue, je peux rendre un partiel avec

<% Html.RenderPartial("AnotherViewModelControl", Model.Child) %>

Dans le partiel je vais le faire

<%= Html.TextBox("Name", Model.Name) %>
or
<%= Html.TextBoxFor(x => x.Name) %>

Cependant, le problème est que les rendra name="Nom" alors que j'ai besoin d'avoir name="Enfant.Le nom de" modèle de classeur pour fonctionner correctement. Ou, nom="Enfant2.Le nom de" quand j'ai rendu la deuxième propriété à l'aide de la même vue partielle.

Comment puis-je faire ma vue partielle de reconnaître automatiquement le préfixe requis? Je peux le passer en paramètre mais c'est trop gênant. C'est encore pire quand je veux par exemple pour la rendre de manière récursive. Est-il un moyen de rendre les vues partielles avec un préfixe, ou, encore mieux, avec l'automatique reconition de l'appel de la lambda expression, afin que les

<% Html.RenderPartial("AnotherViewModelControl", Model.Child) %>

ajoutera automatiquement correcte "de l'Enfant." préfixe pour le nom généré par/id cordes?

Je peux accepter n'importe quelle solution, y compris la 3 ème partie de la vue des moteurs et des bibliothèques - je réellement utiliser Allumage du Moteur d'Affichage (j' "résoudre" le problème à l'aide de ses macros) et MvcContrib, mais ne pas y trouver une solution. XForms, InputBuilder, MVC v2 - n'importe quel outil/insight qui offrent cette fonctionnalité sera grande.

Actuellement, je pense que ce codage moi-même, mais il semble comme une perte de temps, je ne crois pas que ce choses triviales, n'est pas mis en œuvre déjà.

Beaucoup de manuel des solutions existent, et elles sont toutes les bienvenues. Par exemple, je peux forcer mes partiels d'être basé sur IPartialViewModel<T> { public string Prefix; T Modèle; }. Mais je préfère la préfère certains/solution approuvée.

Mise à JOUR: il y a une question similaire, avec pas de réponse ici.

112voto

Mahmoud Moravej Points 1490

Vous pouvez étendre la classe d’aide Html par la présente :

et tout simplement l’utiliser dans votre point de vue comme ceci :

et vous verrez que tout est OK !

101voto

Jokin Points 1809

jusqu’ici, je cherchais la même chose que j’ai trouvé ce récent post :

http://davybrion.com/blog/2011/01/prefixing-Input-Elements-of-partial-views-with-ASP-NET-MVC/

12voto

asoifer1879 Points 31

Ma réponse, fondée sur la réponse de Mahmoud Moravej notamment le commentaire de Ivan Zlatev.

Edit : Réponse de la Mohamoud est incorrect pour le rendu partiel imbriqué. Vous devez ajouter le nouveau préfixe au préfixe vieux, seulement si c’est nécessaire. Ce n’était pas clair dans les dernières réponses ( :

10voto

NickLarsen Points 9591

À l'aide de MVC2 vous pouvez atteindre cet objectif.

Voici la vue fortement typée:

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<MvcLearner.Models.Person>" %>

<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
    Create
</asp:Content>

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">

    <h2>Create</h2>

    <% using (Html.BeginForm()) { %>
        <%= Html.LabelFor(person => person.Name) %><br />
        <%= Html.EditorFor(person => person.Name) %><br />
        <%= Html.LabelFor(person => person.Age) %><br />
        <%= Html.EditorFor(person => person.Age) %><br />
        <% foreach (String FavoriteFoods in Model.FavoriteFoods) { %>
            <%= Html.LabelFor(food => FavoriteFoods) %><br />
            <%= Html.EditorFor(food => FavoriteFoods)%><br />
        <% } %>
        <%= Html.EditorFor(person => person.Birthday, "TwoPart") %>
        <input type="submit" value="Submit" />
    <% } %>

</asp:Content>

Voici la vue fortement typée pour la classe enfant (qui doit être stocké dans un sous-dossier du répertoire view appelé EditorTemplates):

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<MvcLearner.Models.TwoPart>" %>

<%= Html.LabelFor(birthday => birthday.Day) %><br />
<%= Html.EditorFor(birthday => birthday.Day) %><br />

<%= Html.LabelFor(birthday => birthday.Month) %><br />
<%= Html.EditorFor(birthday => birthday.Month) %><br />

Ici, c'est le contrôleur:

public class PersonController : Controller
{
    //
    // GET: /Person/
    [AcceptVerbs(HttpVerbs.Get)]
    public ActionResult Index()
    {
        return View();
    }

    [AcceptVerbs(HttpVerbs.Get)]
    public ActionResult Create()
    {
        Person person = new Person();
        person.FavoriteFoods.Add("Sushi");
        return View(person);
    }

    [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult Create(Person person)
    {
        return View(person);
    }
}

Voici les classes personnalisées:

public class Person
{
    public String Name { get; set; }
    public Int32 Age { get; set; }
    public List<String> FavoriteFoods { get; set; }
    public TwoPart Birthday { get; set; }

    public Person()
    {
        this.FavoriteFoods = new List<String>();
        this.Birthday = new TwoPart();
    }
}

public class TwoPart
{
    public Int32 Day { get; set; }
    public Int32 Month { get; set; }
}

Et la source de sortie:

<form action="/Person/Create" method="post"><label for="Name">Name</label><br /> 
    <input class="text-box single-line" id="Name" name="Name" type="text" value="" /><br /> 
    <label for="Age">Age</label><br /> 
    <input class="text-box single-line" id="Age" name="Age" type="text" value="0" /><br /> 
    <label for="FavoriteFoods">FavoriteFoods</label><br /> 
    <input class="text-box single-line" id="FavoriteFoods" name="FavoriteFoods" type="text" value="Sushi" /><br /> 
    <label for="Birthday_Day">Day</label><br /> 
    <input class="text-box single-line" id="Birthday_Day" name="Birthday.Day" type="text" value="0" /><br /> 

    <label for="Birthday_Month">Month</label><br /> 
    <input class="text-box single-line" id="Birthday_Month" name="Birthday.Month" type="text" value="0" /><br /> 
    <input type="submit" value="Submit" /> 
</form>

Maintenant, c'est terminé. Définissez un point d'arrêt dans la création de Poste de contrôleur de l'action pour vérifier. Ne pas l'utiliser avec des listes cependant, car il l'habitude de travailler. Voir ma question sur l'utilisation de EditorTemplates avec IEnumerable pour en savoir plus.

3voto

cottsak Points 5490

Je suis tombé sur ce problème aussi et après beaucoup de douleur que j’ai trouvé que c’était plus facile pour la refonte mes interfaces telles que j’ai n’a pas besoin de poster dos imbriqué objets du modèle. Cela m’a obligé à changer mon flux de travail interface : bien sûr, j’ai maintenant obligent l’utilisateur à faire en deux étapes, ce que j’ai rêvé de faire sur un, mais la facilité de maintenance facilité d’utilisation et code de la nouvelle approche est de plus grande valeur pour moi maintenant.

Espérons que cela aide certains.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X