web-dev-qa-db-fra.com

Rendu d'une vue partielle lors d'un clic de bouton dans ASP.NET MVC

Le problème que je vais décrire est très similaire à celui que j'ai déjà trouvé (par exemple, ce message avec un nom presque identique ), mais j'espère pouvoir en faire quelque chose qui ne soit pas un doublon.

J'ai créé une nouvelle application ASP.NET MVC 5 dans Visual Studio. Ensuite, j'ai défini deux classes de modèle:

public class SearchCriterionModel
{
  public string Keyword { get; set; }
}

public class SearchResultModel
{
  public int Id { get; set; }
  public string FirstName { get; set; }
  public string Surname { get; set; }
}

Ensuite, j'ai créé le SearchController comme suit:

public class SearchController : Controller
{
  public ActionResult Index()
  {
    return View();
  }

  public ActionResult DisplaySearchResults()
  {
    var model = new List<SearchResultModel>
    {
      new SearchResultModel { Id=1, FirstName="Peter", Surname="Pan" },
      new SearchResultModel { Id=2, FirstName="Jane", Surname="Doe" }
    };
    return PartialView("SearchResults", model);
  }
}

ainsi que les vues Index.cshtml (fortement typé avec SearchCriterionModel en tant que modèle et modèle Edit) et SearchResults.cshtml en tant que partiel vue avec un modèle de type IEnumerable<SearchResultModel> (modèle Liste).

Ceci est la vue Index:

@model WebApplication1.Models.SearchCriterionModel

@{
  ViewBag.Title = "Index";
}

@using (Html.BeginForm())
{
  @Html.AntiForgeryToken()

  <div class="form-horizontal">
    <h4>SearchCriterionModel</h4>
    <hr />
    @Html.ValidationSummary(true, "", new { @class = "text-danger" })
    <div class="form-group">
      @Html.LabelFor(model => model.Keyword, htmlAttributes: new { @class = "control-label col-md-2" })
      <div class="col-md-10">
        @Html.EditorFor(model => model.Keyword, new { htmlAttributes = new { @class = "form-control" } })
        @Html.ValidationMessageFor(model => model.Keyword, "", new { @class = "text-danger" })
      </div>
    </div>

    <div class="form-group">
      <div class="col-md-offset-2 col-md-10">
        <input type="button" id="btnDisplaySearchResults" value="Search" onclick="location.href='@Url.Action("DisplaySearchResults", "SearchController")'" />
      </div>
    </div>
  </div>
}

<div>
  @Html.ActionLink("Back to List", "Index")
</div>
<div id="searchResults">

</div>

Comme vous pouvez le constater, j’ai ajouté un div avec id="searchResults" Sous le modèle standard et modifié le bouton. Ce que je veux, c'est afficher la vue partielle SearchResults.cshtml Dans le div en bas, mais uniquement après avoir cliqué sur le bouton. J'ai réussi à montrer une vue partielle là-bas en utilisant @Html.Partial("SearchResults", ViewBag.MyData), mais elle est rendue lorsque la vue parent est chargée pour la première fois et que j'ai défini ViewBag.MyData Dans la méthode Index() déjà, ce qui n'est pas ce que je veux.

Résumé: En cliquant sur le bouton, je vais obtenir quelques List sur SearchResultModel instances (via un accès à une base de données), puis la vue partielle doit être rendue en utilisant les données nouvellement obtenues comme modèle. Comment puis-je accomplir cela? Je semble déjà avoir échoué à la première étape, c'est-à-dire réagir au clic du bouton avec le code ci-dessus. En ce moment, je navigue vers l'URL ~/Search/DisplaySearchResults, Mais bien sûr il n'y a rien là-bas et aucune méthode code-behind n'est appelée. En ASP.NET traditionnel, je viens d’ajouter un gestionnaire OnClick côté serveur, de définir le DataSource pour une grille et d’afficher la grille. Mais dans MVC, j'échoue déjà avec cette tâche simple ...

Mise à jour: Changer le bouton en @Html.ActionLink Je peux enfin entrer dans la méthode du contrôleur. Mais naturellement, puisqu'il renvoie la vue partielle, il s'affiche comme le contenu de la page entière. La question est donc la suivante: comment indiquer le rendu de la vue partielle à l'intérieur d'un div spécifique côté client?

24
InvisiblePanda

Changer le bouton pour

<button id="search">Search</button>

et ajouter le script suivant

var url = '@Url.Action("DisplaySearchResults", "Search")';
$('#search').click(function() {
  var keyWord = $('#Keyword').val();
  $('#searchResults').load(url, { searchText: keyWord });
})

et modifier la méthode du contrôleur pour accepter le texte de recherche

public ActionResult DisplaySearchResults(string searchText)
{
  var model = // build list based on parameter searchText
   return PartialView("SearchResults", model);
}

La méthode jQuery .load Appelle votre méthode de contrôleur en transmettant la valeur du texte de recherche et met à jour le contenu du <div> Avec la vue partielle.

Note latérale: L'utilisation d'une balise <form> Et de @Html.ValidationSummary() et @Html.ValidationMessageFor() n'est probablement pas nécessaire ici. Votre jamais retourner la vue Index donc ValidationSummary n'a aucun sens et je suppose que vous voulez un texte de recherche null pour renvoyer tous les résultats, et dans tous les cas vous n'avez aucune validation attributs pour la propriété Keyword donc il n’ya rien à valider.

Éditer

D'après les commentaires de l'OP selon lesquels SearchCriterionModel contiendra plusieurs propriétés avec des attributs de validation, l'approche consisterait à inclure un bouton d'envoi et à gérer les formulaires .submit()

<input type="submit" value="Search" />

var url = '@Url.Action("DisplaySearchResults", "Search")';
$('form').submit(function() {
  if (!$(this).valid()) { 
    return false; // prevent the ajax call if validation errors
  }
  var form = $(this).serialize();
  $('#searchResults').load(url, form);
  return false; // prevent the default submit action
})

et la méthode du contrôleur serait

public ActionResult DisplaySearchResults(SearchCriterionModel criteria)
{
  var model = // build list based on the properties of criteria
  return PartialView("SearchResults", model);
}
56
user3559349

Donc, voici le code du contrôleur.

public IActionResult AddURLTest()
{
    return ViewComponent("AddURL");
}

Vous pouvez le charger à l'aide de la méthode de chargement JQuery.

$(document).ready (function(){
    $("#LoadSignIn").click(function(){
        $('#UserControl').load("/Home/AddURLTest");
    });
});

source lien de code

1