2010-12-15 21 views
1

J'ai une page maître qui doit afficher certaines données de ma base de données. Par exemple, j'ai un en-tête dans la page qui affichera le nombre de messages/alertes qu'un utilisateur a. Chaque contrôleur aura besoin de transmettre ces données à la vue. Quel est le meilleur moyen de le faire dans une application MVC? Je ne veux évidemment pas copier le code dans chaque action du contrôleur.Données dynamiques de la page maître MVC

Répondre

2

Une alternative à la réponse de Darin est un ActionFilterAttribute, qui plonge les données dans ViewData de chaque Action. Où vous placez l'attribut définit quelles actions obtiennent ceci. Le placer à une classe de contrôleur racine signifie que toutes les actions l'obtiendront.

+0

Je pense que je vais essayer cette méthode opposée à l'essai des actions enfants. Je n'aime pas la solution Model Factory parce que je ne pense pas que chaque modèle devrait hériter d'une classe de modèle de base. – Dismissile

3

Vous pouvez utiliser des actions enfants. Phil Haack fait un excellent travail en les expliquant dans ce blog post. De cette façon, vous auriez un contrôleur spécifique pour extraire les données du référentiel et les transmettre à sa propre vue partielle. Ensuite, dans la page principale vous suffit d'inclure l'action:

<%= Html.Action("index", "somecontroller") %> 

De cette façon, d'autres contrôleurs ne doivent pas transmettre les données à la vue. Il a un cycle de vie complètement séparé.

+0

+1 agréable et simple – hunter

+0

peut-être pour plus de clarté: '<% = Html.Action (" GetMessages "," MessagesController ")%>' et '<% ​​= Html.Action (" GetAlerts "," AlertsController ")% > – hunter

+1

Les actions pour enfants ont leurs inconvénients. Ils forcent les vues à être trop conscientes de ce qui se passe. Ils sont également assez coûteux car le système doit simuler une seconde requête complète. Rails avait l'habitude d'avoir des fonctionnalités similaires, mais il a finalement été retiré. –

2

Vous pourriez avoir un modèle que tous les modèles héritent de:

public abstract class MasterModel 
{ 
    public int NumberOfMessages { get; set; } 
    public string Username { get; set; } 
} 

Et alors vous pourriez avoir une sorte d'usine modèle qui permettra de créer le modèle demandé:

public class ModelFactory : IModelFactory 
{ 

    private IUserRepository userRepository; 

    public ModelFactory(IUserRepository userRepository) 
    { 
     // Inject a repository .. or a service... 
     this.userRepository = userRepository; 
    } 

    public T Create<T>() where T : MasterModel, new() 
    { 
     var m = new T() 
     { 
      NumberOfMessages = this.userRepository.GetNumberMessages(currentUser) // Get current user somehow... HttpContext 
     }; 
     return m; 

    } 
} 

Alors vous » d injectez IModelFactory dans votre contrôleur et utilisez-le dans l'action:

[HttpGet] 
public ViewResult DoSomething() 
{ 
    var model = this.modelFactory.Create<MyActionModel>(); 
    return View(model); 
} 

en votre maître a le type de modèle MasterModel et peut ensuite utiliser cette information. De cette façon, toute votre logique peut être conservée dans un service/référentiel injecté dans l'usine qui crée le modèle de chaque vue. C'est ce que je fais et ça marche super bien.