MVC 3: Comment rendre une vue sans sa page de mise en page lorsqu'elle est chargée via ajax?

J'apprends à propos de amélioration Progressive et j'ai une question sur les vues AJAXifying. Dans mon projet MVC 3, j'ai une page de mise en page, une page viewstart et deux vues simples.

La page viewstart se trouve à la racine du dossier Views et s'applique donc à toutes les vues. Il spécifie que toutes les vues doivent utiliser _Layout.cshtml pour leur page de mise en page. La mise en page contient deux liens de navigation, un pour chaque vue. Les liens utilisent @Html.ActionLink() pour se rendre à la page.

Maintenant Je ont ajouté jQuery et veulent détourner ces liens et utiliser Ajax pour charger leur contenu sur la page dynamiquement.

<script type="text/javascript">
    $(function () {
        $('#theLink').click(function () {
            $.ajax({
                url: $(this).attr('href'),
                type: "GET",
                success: function (response) {
                    $('#mainContent').html(response);
                }
            });
            return false;
        });
    });
</script>

Il y a deux façons de penser pour le faire, mais je n'aime pas particulièrement l'une ou l'autre:

1) je peux prendre le contenu de la vue entière et les placer dans une vue partielle, puis demander à la vue principale d'appeler la vue partielle lorsqu'elle est rendue. De cette façon, en utilisant Request.IsAjaxRequest() dans le contrôleur, je peux retourner View() ou retourner PartialView() selon que la requête est ou non un Ajax demande. Je ne peux pas retourner la vue régulière à la requête Ajax car alors il utiliserait la page de mise en page et j'obtiendrais une deuxième copie de la page de mise en page injectée. Cependant, je n'aime pas cela car cela me force à créer des vues vides avec juste un @{Html.RenderPartial();} pour les requêtes GET standard.

    public ActionResult Index()
    {
        if (Request.IsAjaxRequest())
            return PartialView("partialView");
        else
            return View();
    }

Puis dans L'Index.cshtml faites ceci:

@{Html.RenderPartial("partialView");}

2) je peux supprimer la désignation de mise en page de _viewstart et la spécifier manuellement lorsque la requête N'est pas Ajax:

    public ActionResult Index()
    {
        if (Request.IsAjaxRequest())
            return View(); // Return view with no master.
        else
            return View("Index", "_Layout"); // Return view with master.
    }

Est-ce que quelqu'un avez une meilleure suggestion? Existe-t-il un moyen de retourner une vue sans sa page de mise en page? Il serait beaucoup plus facile de dire explicitement "ne pas inclure votre mise en page" s'il s'agit d'une requête ajax, que d'inclure explicitement la mise en page si ce n'est pas un ajax.

147
demandé sur Chev 2011-03-16 00:37:27

6 réponses

Dans ~/Views/ViewStart.cshtml:

@{
    Layout = Request.IsAjaxRequest() ? null : "~/Views/Shared/_Layout.cshtml";
}

Et dans le contrôleur:

public ActionResult Index()
{
    return View();
}
245
répondu Darin Dimitrov 2011-03-15 21:41:24

Il suffit de mettre le code suivant en haut de la page

@{
    Layout = "";
}
87
répondu roncansan 2011-12-22 01:43:17

Je préfère, et utilise, votre option # 1. Je n'aime pas #2 parce que pour moi View() implique que vous retournez une page entière. Il devrait s'agir d'une page HTML entièrement étoffée et valide une fois le moteur de vue terminé. PartialView() a été créé pour renvoyer des morceaux arbitraires de HTML.

Je ne pense pas que ce soit une grosse affaire d'avoir une vue qui appelle juste un partiel. Il est encore sec, et vous permet d'utiliser la logique du partiel dans deux scénarios.

Beaucoup de gens n'aiment pas fragmenter l'appel de leur action chemins avec Request.IsAjaxRequest(), et je peux l'apprécier. Mais IMO, si tout ce que vous faites est de décider d'appeler View() ou PartialView() alors la branche n'est pas une grosse affaire et est facile à maintenir (et à tester). Si vous vous trouvez en utilisant IsAjaxRequest() pour déterminer de grandes parties de la façon dont votre action se déroule, alors faire une action AJAX séparée est probablement mieux.

13
répondu Matt Greer 2011-03-15 21:43:11

Créer deux mise en page: 1. mise en page vide, 2 . mise en page principale, puis écrire dans le fichier _viewStart ce code:

@{
if (Request.IsAjaxRequest())
{
    Layout = "~/Areas/Dashboard/Views/Shared/_emptyLayout.cshtml";
}
else
{
    Layout = "~/Areas/Dashboard/Views/Shared/_Layout.cshtml";
}}

Bien sûr, peut-être que ce n'est pas la meilleure solution

13
répondu Arash Karami 2011-10-24 09:07:19

Vous n'avez pas besoin de créer une vue vide pour cela.

Dans le contrôleur:

if (Request.IsAjaxRequest())
  return PartialView();
else
  return View();

Le Retour D'un PartialViewResult remplacera la définition de mise en page lors du rendu des respons.

6
répondu Souhaieb Besbes 2016-02-11 13:17:37

Pour une application Ruby on Rails, j'ai pu empêcher le chargement d'une mise en page en spécifiant render layout: false dans l'action du contrôleur que je voulais répondre avec ajax html.

-4
répondu user4381244 2014-12-20 18:22:35