NOTE: Apart from
(and even then it's questionable, I'm Scottish). These are machine translated in languages I don't read. If they're terrible please contact me.
You can see how this translation was done in this article.
Friday, 16 August 2024
//Less than a minute
Löydät kaikki lähdekoodit blogikirjoituksista GitHub
Osat 1 ja 2 sarjasta, joka koskee Entity Frameworkin lisäämistä.NET Core -hankkeeseen.
Osa 1 löytyy täällä.
Osa 2 löytyy täällä.
Edellisissä osissa perustimme tietokannan ja taustan blogikirjoituksillemme ja lisäsimme palvelut vuorovaikutukseen tietokannan kanssa. Tässä viestissä kerromme yksityiskohtaisesti, miten nämä palvelut toimivat nyt olemassa olevien ohjaajien ja näkökantojen kanssa.
[TÄYTÄNTÖÖNPANO
Out controllers for Blogs on todella melko yksinkertainen, kuten välttää "Fat Controller" antipattern (kuvio ideinfied aikaisin ASP.NET MVC päivinä).
I MVC-kehysten hyvä käytäntö on tehdä mahdollisimman vähän ohjainmenetelmissä. Tämä johtuu siitä, että rekisterinpitäjä on vastuussa pyynnön käsittelystä ja vastauksen palauttamisesta. Sen ei pitäisi olla vastuussa sovelluksen liiketoimintalogiikasta. Tämä on mallin vastuulla.
"Läskiohjaimen" antipattern on paikka, jossa ohjain tekee liikaa. Tämä voi johtaa useisiin ongelmiin, kuten:
Blogiohjain on suhteellisen yksinkertainen. Siinä on neljä päätointa (ja yksi "komppania" vanhoille blogilinkeille). Nämä ovat seuraavat:
Task<IActionResult> Index(int page = 1, int pageSize = 5)
Task<IActionResult> Show(string slug, string language = BaseService.EnglishLanguage)
Task<IActionResult> Category(string category, int page = 1, int pageSize = 5)
Task<IActionResult> Language(string slug, string language)
IActionResult Compat(string slug, string language)
Nämä toimet puolestaan kutsuvat IBlogService
Saada tarvitsemansa tiedot. Erytropoietiini IBlogService
on yksityiskohtaisesti edellinen virka.
Nämä toimet puolestaan ovat seuraavat:
page
sekä pageSize
muuttujina. Tämä on paginaatiosta. Tulosten perusteella.slug
Euroopan parlamentin ja neuvoston asetus (EU) N:o 1316/2013, annettu 11 päivänä joulukuuta 2013, Euroopan aluekehitysrahastosta (EUVL L 347, 20.12.2013, s. 6). language
muuttujina. THis on menetelmä, jolla luet tätä blogikirjoitusta.category
, page
sekä pageSize
muuttujina.slug
sekä language
muuttujina.slug
sekä language
muuttujina.Kuten on mainittu aiempaa virkaa toteutamme OutputCache
sekä ResponseCahce
säilöä blogikirjoitusten tulokset. Tämä parantaa käyttökokemusta ja vähentää palvelimen kuormitusta.
Ne toteutetaan käyttäen asianmukaisia Action Decorators, jotka määrittelevät parametrit, joita toimintoon käytetään (sekä hx-request
HTMX-pyynnöille). Tutkimukseen, jossa Index
täsmennämme näitä:
[ResponseCache(Duration = 300, VaryByHeader = "hx-request", VaryByQueryKeys = new[] {nameof(page), nameof(pageSize)}, Location = ResponseCacheLocation.Any)]
[OutputCache(Duration = 3600, VaryByHeaderNames = new[] {"hx-request"} ,VaryByQueryKeys = new[] { nameof(page), nameof(pageSize)})]
Näkemykset blogiin ovat suhteellisen yksinkertaiset. Ne ovat enimmäkseen vain lista blogikirjoituksista, joissa on muutama yksityiskohta kutakin viestiä varten. Näkemykset ovat Views/Blog
Kansio. Tärkeimmät näkemykset ovat seuraavat:
_PostPartial.cshtml
Tämä on osittainen näkemys yhdestä blogikirjoituksesta. Sitä käytetään meidän Post.cshtml
näkymä.
@model Mostlylucid.Models.Blog.BlogPostViewModel
@{
Layout = "_Layout";
}
<partial name="_PostPartial" model="Model"/>
_BlogSummaryList.cshtml
Tämä on osittainen näkemys blogikirjoitusten listalle. Sitä käytetään meidän Index.cshtml
näkymä sekä kotisivulla.
@model Mostlylucid.Models.Blog.PostListViewModel
<div class="pt-2" id="content">
@if (Model.TotalItems > Model.PageSize)
{
<pager
x-ref="pager"
link-url="@Model.LinkUrl"
hx-boost="true"
hx-push-url="true"
hx-target="#content"
hx-swap="show:none"
page="@Model.Page"
page-size="@Model.PageSize"
total-items="@Model.TotalItems"
class="w-full"></pager>
}
@if(ViewBag.Categories != null)
{
<div class="pb-3">
<h4 class="font-body text-lg text-primary dark:text-white">Categories</h4>
<div class="flex flex-wrap gap-2 pt-2">
@foreach (var category in ViewBag.Categories)
{
<a hx-controller="Blog" hx-action="Category" hx-push-url="true" hx-get hx-target="#contentcontainer" hx-route-category="@category" href>
<span class="inline-block rounded-full dark bg-blue-dark px-2 py-1 font-body text-sm text-white outline-1 outline outline-green-dark dark:outline-white">@category</span>
</a>
}
</div>
</div>
}
@foreach (var post in Model.Posts)
{
<partial name="_ListPost" model="post"/>
}
</div>
Tässä käytetään _ListPost
Osittainen näkymä yksittäisten blogikirjoitusten esittelyyn hakutarra-auttaja jonka avulla voimme sivuta blogikirjoituksia.
_ListPost.cshtml
Erytropoietiini _Listapostin osittaista katselua käytetään listan yksittäisten blogikirjoitusten näyttämiseen. Sitä käytetään _BlogSummaryList
näkymä.
@model Mostlylucid.Models.Blog.PostListModel
<div class="border-b border-grey-lighter pb-8 mb-8">
<a asp-controller="Blog" asp-action="Show" hx-boost="true" hx-swap="show:window:top" hx-target="#contentcontainer" asp-route-slug="@Model.Slug"
class="block font-body text-lg font-semibold transition-colors hover:text-green text-blue-dark dark:text-white dark:hover:text-secondary">@Model.Title</a>
<div class="flex space-x-2 items-center py-4">
@foreach (var category in Model.Categories)
{
<a hx-controller="Blog" hx-action="Category" class="rounded-full bg-blue-dark font-body text-sm text-white px-2 py-1 outline outline-1 outline-white" hx-push-url="true" hx-get hx-target="#contentcontainer" hx-route-category="@category" href>@category
</a>
}
@{ var languageModel = (Model.Slug, Model.Languages, Model.Language); }
<partial name="_LanguageList" model="languageModel"/>
</div>
<div class="block font-body text-black dark:text-white">@Model.Summary</div>
<div class="flex items-center pt-4">
<p class="pr-2 font-body font-light text-primary light:text-black dark:text-white">
@Model.PublishedDate.ToString("f")
</p>
<span class="font-body text-grey dark:text-white">//</span>
<p class="pl-2 font-body font-light text-primary light:text-black dark:text-white">
@Model.ReadingTime
</p>
</div>
</div>
Koska olet täällä, meillä on linkki yksittäiseen blogikirjoitukseen, postin kategorioihin, kieliin, joilla viesti on saatavilla, postin tiivistelmään, julkaistuun päivämäärään ja lukuaikaan.
Meillä on myös HTMX-linkkitunnisteet kategorioihin ja kieliin, jotta voimme näyttää lokalisoituja virkoja ja tietyn kategorian virkoja.
Meillä on tässä kaksi tapaa käyttää HTMX:ää, joista toinen antaa koko URL-osoitteen ja toinen on "vain HTML" (ts. ei URL-osoitetta). Tämä johtuu siitä, että haluamme käyttää koko URL-osoitetta kategorioihin ja kieliin, mutta emme tarvitse koko URL-osoitetta yksittäiseen blogikirjoitukseen.
<a asp-controller="Blog" asp-action="Show" hx-boost="true" hx-swap="show:window:top" hx-target="#contentcontainer" asp-route-slug="@Model.Slug"
Tämä lähestymistapa kokoaa täydellisen URL-osoitteen yksittäiseen blogikirjoitukseen ja käyttää hx-boost
HTMX:n käyttöpyynnön "vahvistamiseksi" (tämä asettaa hx-request
Otsikko true
).
<a hx-controller="Blog" hx-action="Category" class="rounded-full bg-blue-dark font-body text-sm text-white px-2 py-1 outline outline-1 outline-white" hx-push-url="true" hx-get hx-target="#contentcontainer" hx-route-category="@category" href>@category
</a>
Vaihtoehtoisesti tämä lähestymistapa käyttää HTMX-tunnisteita saadakseen kategoriat blogikirjoituksiin. Tässä käytetään hx-controller
, hx-action
, hx-push-url
, hx-get
, hx-target
sekä hx-route-category
tagit, joilla voit saada kategoriat blogikirjoituksiin, kun taas hx-push-url
on asetettu true
URL-osoitteen siirtämiseksi selaimen historiaan.
Sitä käytetään myös meidän Index
Toimintatapa HTMX-pyyntöihin.
public async Task<IActionResult> Index(int page = 1, int pageSize = 5)
{
var posts =await blogService.GetPagedPosts(page, pageSize);
if(Request.IsHtmx())
{
return PartialView("_BlogSummaryList", posts);
}
posts.LinkUrl = Url.Action("Index", "Blog");
return View("Index", posts);
}
Jos se antaa meille mahdollisuuden joko palauttaa koko näkymän tai vain osittaisen näkymän HTMX-pyyntöihin ja antaa "SPA:n" kaltaisen kokemuksen.
• • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • HomeController
viittaamme myös näihin blogipalveluihin, jotta saamme tuoreimmat blogikirjoitukset etusivulle. Tämä tapahtuu Index
toimintatapa.
public async Task<IActionResult> Index(int page = 1,int pageSize = 5)
{
var authenticateResult = GetUserInfo();
var posts =await blogService.GetPagedPosts(page, pageSize);
posts.LinkUrl= Url.Action("Index", "Home");
if (Request.IsHtmx())
{
return PartialView("_BlogSummaryList", posts);
}
var indexPageViewModel = new IndexPageViewModel
{
Posts = posts, Authenticated = authenticateResult.LoggedIn, Name = authenticateResult.Name,
AvatarUrl = authenticateResult.AvatarUrl
};
return View(indexPageViewModel);
}
Kuten näette täällä, käytämme... IBlogService
saat uusimmat blogikirjoitukset kotisivulle. Käytämme myös GetUserInfo
tapa, jolla käyttäjätiedot saadaan kotisivulle.
Tässäkin on HTMX-pyyntö palauttaa osittainen näkymä blogikirjoituksiin, jotta voimme sivuta blogikirjoituksia kotisivulla.
Seuraavassa osassa mennään tuskalliseen yksityiskohtaan siitä, miten käytämme IMarkdownBlogService
Kantaa tietokantaa markown-tiedostojen blogikirjoituksilla. Tämä on keskeinen osa sovellusta, koska sen avulla voimme käyttää markdown-tiedostoja tietokannan kansoittamiseen blogikirjoituksilla.