上一篇完成了博客的分頁查詢文章列表頁面的數據綁定和分頁功能,本篇將繼續完成剩下的幾個頁面。html
在開始主題以前從新解決上一篇的最後一個問題,當點擊了頭部組件的/posts
連接時直接強制刷新了頁面,通過查看文檔和實踐有了更好的解決方案。git
先將頭部組件Header.razor
中的NavLink
恢復成<NavLink class="menu-item" href="posts">Posts</NavLink>
,不須要點擊事件了。github
而後在Posts.razor
中添加生命週期函數OnParametersSetAsync()
,在初始化完成後執行。緩存
/// <summary> /// 初始化完成後執行 /// </summary> /// <returns></returns> protected override async Task OnParametersSetAsync() { if (!page.HasValue) { page = 1; await RenderPage(page); } }
判斷當前page參數是否有值,有值的話說明請求確定是來自於翻頁,當page沒有值的時候就說明是頭部的菜單點進來的。那麼此時給page賦值爲1,調用API加載數據便可。app
Categories.razor
是分類列表頁面,上篇文章已經實現了從API獲取數據的方法,因此這裏就很簡單了,指定接受類型,而後在生命週期初始化OnInitializedAsync()
中去獲取數據。async
@code{ /// <summary> /// categories /// </summary> private ServiceResult<IEnumerable<QueryCategoryDto>> categories; /// <summary> /// 初始化 /// </summary> protected override async Task OnInitializedAsync() { // 獲取數據 categories = await Http.GetFromJsonAsync<ServiceResult<IEnumerable<QueryCategoryDto>>>($"/blog/categories"); } }
當獲取到數據的時候進行綁定,沒有數據的時候仍是顯示加載中的組件<Loading />
讓他轉圈圈。ide
@if (categories == null) { <Loading /> } else { <div class="container"> <div class="post-wrap categories"> <h2 class="post-title">- Categories -</h2> <div class="categories-card"> @if (categories.Success && categories.Result.Any()) { @foreach (var item in categories.Result) { <div class="card-item"> <div class="categories"> <a href="/category/@item.DisplayName/"> <h3> <i class="iconfont iconcode" style="padding-right:3px"></i> @item.CategoryName </h3> <small>(@item.Count)</small> </a> </div> </div> } } else { <ErrorTip /> } </div> </div> </div> }
直接循環返回的數據列表categories.Result
,綁定數據就好,當獲取失敗或者沒有返回數據的時候顯示錯誤提示組件<ErrorTip />
函數
Categories.razor
是標籤列表頁面,和分類列表HTML結構差很少同樣的,除了返回類型和接口地址不同,將上面代碼複製過來改改便可。post
@code{ /// <summary> /// tags /// </summary> private ServiceResult<IEnumerable<QueryTagDto>> tags; /// <summary> /// 初始化 /// </summary> protected override async Task OnInitializedAsync() { // 獲取數據 tags = await Http.GetFromJsonAsync<ServiceResult<IEnumerable<QueryTagDto>>>($"/blog/tags"); } }
@if (tags == null) { <Loading /> } else { <div class="container"> <div class="post-wrap tags"> <h2 class="post-title">- Tags -</h2> <div class="tag-cloud-tags"> @if (tags.Success && tags.Result.Any()) { @foreach (var item in tags.Result) { <a href="/tag/@item.DisplayName/">@item.TagName<small>(@item.Count)</small></a> } } else { <ErrorTip /> } </div> </div> </div> }
FriendLinks.razor
是友情連接列表頁面,實現方式和上面兩個套路如出一轍。優化
@code { /// <summary> /// friendlinks /// </summary> private ServiceResult<IEnumerable<FriendLinkDto>> friendlinks; /// <summary> /// 初始化 /// </summary> protected override async Task OnInitializedAsync() { // 獲取數據 friendlinks = await Http.GetFromJsonAsync<ServiceResult<IEnumerable<FriendLinkDto>>>($"/blog/friendlinks"); } }
@if (friendlinks == null) { <Loading /> } else { <div class="container"> <div class="post-wrap categories"> <h2 class="post-title">- FriendLinks -</h2> <div class="categories-card"> @if (friendlinks.Success && friendlinks.Result.Any()) { @foreach (var item in friendlinks.Result) { <div class="card-item"> <div class="categories"> <a target="_blank" href="@item.LinkUrl"> <h3>@item.Title</h3> </a> </div> </div> } } else { <ErrorTip /> } </div> </div> </div> }
Posts.Category.razor
是根據分類查詢文章列表頁面,他接受一個參數name,咱們要根據name去API查詢數據而後綁定頁面便可。
這裏的參數name實際上就是從標籤列表傳遞過來的DisplayName
的值,它是一個比較友好的名稱,咱們還要經過這個值去查詢真正的分類名稱進行展現,因此這裏須要調用兩個API,這點在設計API的時候沒有考慮好,咱們其實能夠將這兩個API合併變成一個,後續再進行優化吧,這裏就請求兩次。
添加兩個接收參數:分類名稱和返回的文章列表數據。
/// <summary> /// 分類名稱 /// </summary> private string categoryName; /// <summary> /// 文章列表數據 /// </summary> private ServiceResult<IEnumerable<QueryPostDto>> posts;
而後在OnInitializedAsync()
初始化方法中調用API獲取數據,賦值給變量。
/// <summary> /// 初始化 /// </summary> protected override async Task OnInitializedAsync() { // TODO:獲取數據,能夠在API中合併這兩個請求。 var category = await Http.GetFromJsonAsync<ServiceResult<string>>($"/blog/category?name={name}"); posts = await Http.GetFromJsonAsync<ServiceResult<IEnumerable<QueryPostDto>>>($"/blog/posts/category?name={name}"); if (category.Success) { categoryName = category.Result; } }
有了數據,直接在頁面上進行循環綁定。
@if (posts == null) { <Loading /> } else { <div class="container"> <div class="post-wrap tags"> @if (categoryName != null) { <h2 class="post-title">- Category · @categoryName -</h2> } </div> <div class="post-wrap archive"> @if (posts.Success && posts.Result.Any()) { @foreach (var item in posts.Result) { <h3>@item.Year</h3> @foreach (var post in item.Posts) { <article class="archive-item"> <NavLink href="@("/post"+post.Url)">@post.Title</NavLink> <span class="archive-item-date">@post.CreationTime</span> </article> } } } else { <ErrorTip /> } </div> </div> }
Posts.Tag.razor
是根據標籤查詢文章列表,這個和分類查詢文章列表實現方式同樣,直接上代碼。
@code { /// <summary> /// 標籤名稱參數 /// </summary> [Parameter] public string name { get; set; } /// <summary> /// 標籤名稱 /// </summary> private string tagName; /// <summary> /// 文章列表數據 /// </summary> private ServiceResult<IEnumerable<QueryPostDto>> posts; /// <summary> /// 初始化 /// </summary> protected override async Task OnInitializedAsync() { // TODO:獲取數據,能夠在API中合併這兩個請求。 var tag = await Http.GetFromJsonAsync<ServiceResult<string>>($"/blog/tag?name={name}"); posts = await Http.GetFromJsonAsync<ServiceResult<IEnumerable<QueryPostDto>>>($"/blog/posts/tag?name={name}"); if (tag.Success) { tagName = tag.Result; } } }
@if (posts == null) { <Loading /> } else { <div class="container"> <div class="post-wrap tags"> @if (tagName != null) { <h2 class="post-title">- Tag · @tagName -</h2> } </div> <div class="post-wrap archive"> @if (posts.Success && posts.Result.Any()) { @foreach (var item in posts.Result) { <h3>@item.Year</h3> @foreach (var post in item.Posts) { <article class="archive-item"> <NavLink href="@("/post"+post.Url)">@post.Title</NavLink> <span class="archive-item-date">@post.CreationTime</span> </article> } } } else { <ErrorTip /> } </div> </div> }
以上完成了以上幾個頁面的數據綁定,頁面之間的跳轉已經關聯起來了,而後還剩下文章詳情頁,你們能夠先本身動手完成它,今天就到這裏,未完待續...