42
loading...
This website collects cookies to deliver better user experience
// GET: Movies
public async Task<IActionResult> Index() { ... }
// GET: Movies/Details/5
public async Task<IActionResult> Details(int? id) { ... }
// GET: Movies/Create
public IActionResult Create() { ... }
// POST: Movies/Create
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create(MovieEditorViewModel model) { ... }
// GET: Movies/Edit/5
public async Task<IActionResult> Edit(int? id) { ... }
// POST: Movies/Edit/5
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Edit(int id, MovieEditorViewModel model) { ... }
// GET: Movies/Delete/5
public async Task<IActionResult> Delete(int? id) { ... }
// POST: Movies/Delete/5
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public async Task<IActionResult> DeleteConfirmed(int id) { ... }
<script src="https://unpkg.com/[email protected]"></script>
dans mon fichier "/Views/Shared/_Layout.cshtml" :...
<div class="container">
© 2021 - MvcHtmx - @DateTime.Now.ToLongTimeString()
</div>
</footer>
<script src="~/lib/jquery/dist/jquery.min.js"></script>
<script src="~/js/site.js" asp-append-version="true"></script>
<script src="https://unpkg.com/[email protected]"></script>
@await RenderSectionAsync("Scripts", required: false)
</body>
</html>
<a asp-action="Create">Créer</a>
dans l'en-tête de la table pour permettre de créer un nouveau film.<a href="/movies/create/">Créer</a>
. Lorsque l'utilisateur clique sur ce lien, le navigateur contacte le serveur web via une requête HTTP GET et ASP.NET Core exécute l'action "Create" du contrôleur "MoviesController" qui renvoie une nouvelle page au navigateur.@RenderBody()
. Et d'un point de vue HTML, ce qui change, c'est le contenu de la balise <main>
.</header>
<div class="container">
<main role="main" class="pb-3">
@RenderBody()
</main>
</div>
<footer class="border-top footer text-muted">
<main>
.hx-get="/movies/create/"
pour indiquer à HTMX qu'il devra faire une requête HTTP GET sur l'URL "/movies/create/" qui correspond à l'action "Create" du contrôleur "MoviesController".hx-target="main"
pour cibler où HTMX va devoir insérer le contenu renvoyé par l'action (à la place du contenu en cours de la balise <main>
).hx-push-url="true"
pour que la barre d'adresse du navigateur soit mise à jour. <td>
<a asp-action="Create" hx-target="main" hx-push-url="true" hx-get="/movies/create/">Créer</a>
</td>
<td>
<a href="/movies/create/" hx-target="main" hx-push-url="true" hx-get="/movies/create/">Créer</a>
</td>
<a href="/movies/create/" hx-target="main" hx-push-url="true">Créer</a>
pour éviter que les attributs "href" et "hx-get" fassent doublon.<td>
<a asp-action="Edit" asp-route-id="@item.Movie_ID"
hx-target="main" hx-push-url="true" hx-get="/movies/edit/@item.Movie_ID/">Modifier</a> |
<a asp-action="Details" asp-route-id="@item.Movie_ID"
hx-target="main" hx-push-url="true" hx-get="/movies/details/@item.Movie_ID/">Consulter</a> |
<a asp-action="Delete" asp-route-id="@item.Movie_ID"
hx-target="main" hx-push-url="true" hx-get="/movies/delete/@item.Movie_ID/">Supprimer</a>
</td>
<a href="/movies/">Annuler</a>
pour quitter la page et revenir à la liste des films. Ce lien est généré via le TagHelper suivant :<a asp-action="Index">Annuler</a>
<a asp-action="Index" hx-target="main" hx-push-url="true" hx-get="/movies/">Annuler</a>
<a asp-action="Edit" asp-route-id="@Model.Movie_ID" class="btn btn-secondary"
hx-target="main" hx-push-url="true" hx-get="/movies/edit/@Model.Movie_ID/">Modifier</a>
<form asp-action="Create" method="post" class="form-horizontal">
...
</form>
asp-action="Create"
parce que je fais en sorte de toujours poster un formulaire sur la même URL que celle qui affiche ce formulaire. C'est beaucoup mieux si jamais il y a des erreurs de saisie détectées après coup côté serveur.<form method="post" class="form-horizontal">
...
</form>
<form method="post" class="form-horizontal" hx-post="/movies/create/">
...
</form>
<form method="post" class="form-horizontal" hx-post="/movies/edit/@Model.Movie_ID/">
...
</form>
<form method="post" class="form-horizontal" hx-post="/movies/delete/@Model.Movie_ID/">
...
</form>
return View(data)
. Le système de vues de ASP.NET Core combine alors les informations de ce modèle, le code Razor de la vue et le code Razor du layout pour générer une page HTML complète qu'il renvoie au navigateur.return View(data)
, on peut aussi faire un return PartialView(data)
et dans ce cas le layout n'est pas pris en compte. if (Request.Headers.ContainsKey("HX-Request"))
{
// Cas où on vient depuis HTMX
return PartialView(model);
}
return View(model); // Cas où on n'est pas passé par HTMX
private IActionResult HtmxView(object model)
{
if (Request.Headers.ContainsKey("HX-Request"))
{
Response.Headers.Add("HX-Push", Request.Path.ToString());
return PartialView(model);
}
return View(model);
}
hx-push-url="true"
que j'avais ajouté au niveau de chaque lien <a>
. Je peux donc les supprimer sans perdre en fonctionnalités.<script src="https://unpkg.com/[email protected]"></script>
dans le layout.<a asp-action="Toto">Tutu</a>
par <a asp-action="Toto" hx-target="main" hx-get="/movies/toto/">Tutu</a>
hx-target="main" hx-get="/movies/toto/@Un_ID/"
aux liens <a asp-action="Toto" asp-route-id="@Un_ID">Tutu</a>
<form method="post" ...
par <form method="post" hx-post="/movies/toto/xxx" ...
return View(model);
par des return HtmxView(model);
private IActionResult HtmxView(object model) { ... }
au contrôleur<a-htmx>
et <form-htmx>
pour que toutes ces modifications soient moins tarabiscotées (et pour éviter les doublons entre "href" et "hx-get"). <a asp-action="Toto">Tutu</a>
à <a-htmx asp-action="Toto">Tutu</a-htmx>
!