Paging TagHelfer v1.0.0:企业企管 @ -对现代 ASP}.NET核心的重新缓冲
来之不易,即将到来 追踪GitHub! .
这只是为了向你们展示我在这个控制器上的进展... ...#!_It'_Ill是值得等待的#MS K2}
一. 导言导言 导言 导言 导言
在经过数月的进化和来自社群的宝贵反馈后, @(5.7k+下载@!),I'm 兴奋地宣布PageTagHelfer图书馆已进入版本{1.0.0.这是'}这只是一个拼接数字的翻版{MS K6它代表了图书馆完全成熟的功能,具有适合真正“-world},生产应用程序}MSC9}
如果你一直关注这个系列 , ưμ㼯A添加“,” 可排序排序标题, 并提取 页面大小控件“.”版本“1.0.0”将我们学到的所有东西都带走,并添加了关键的企业特征“MSC3”
- 继续调制 用于 noSQL 数据库 : @(Cmos DB,DynamoDB,Azure表格存储@)
- 多语种本地化 支持“8”的语言
- 弹性 JavaScript 模式 从 HTMX 到零@ - @ JavaScript
- 纯粹反向视图 没有DisaudisUI依赖性
- 智能 URL 参数保护 横贯所有导航
- HTMX 2.0.4 具有后向兼容性升级
让'沉入其中的每一个特征中, 看看他们如何合作 创造出真正灵活的页码解决方案
继续调整调控 {# @csurvation\ -}token@token_-#pagination=}
与 SQL 数据库一起,传统页式工作非常出色,您可以很容易地使用 SKIP 和 TAKE @.}但是如果你在像宇宙 DB ,Dynamoddab,或Azure表格存储@?这样的 NoSQL 数据库中工作,这些数据库会怎样呢? 续序号.
理解 Token@ - @ 基于 Pagination @ MS K1_ 了解 @ k2 @ token @ I-} (基于 @ MPK4 @ pagrination @ })
这里“ ' @% 1” 表示继续象征性的外观与传统的 page@ MS K1} 有何不同?
graph TD
A[Traditional Paging] --> B[Page 1: OFFSET 0 LIMIT 10]
A --> C[Page 2: OFFSET 10 LIMIT 10]
A --> D[Page 3: OFFSET 20 LIMIT 10]
E[Token-Based Paging] --> F[Page 1: No token]
F --> G[Returns: Data + Token_A]
G --> H[Page 2: Token_A]
H --> I[Returns: Data + Token_B]
I --> J[Page 3: Token_B]
style A stroke:#0ea5e9,stroke-width:3px
style E stroke:#ec4899,stroke-width:3px
传统Paging:
- 您精确指定要检索哪些记录@ ( @ OFFSET+/ @ LIMIT)}
- 您可以直接跳转到任何页面
- 数据库必须扫描前所有记录
调制解密@ - @ 基于 Pageing+:}
- 数据库返回一个不透明的标牌,代表 "}在哪个位置可以继续\ MPK1\
- Token 格式是数据库@-} 特定且客户端不透明
- 前向导航是自然的 , 后向导航需要象征性的历史
继续页面执行@{# @csurvation @-_pager}-#implementation=}
新的 <continuation-pager> 标签帮助工具使执行标记@ - @ 基于 passion 以直截了当 <% MS K1} first,} 创建一个模式来实施 IContinuationPagingModel:
public class ProductPagingViewModel : IContinuationPagingModel
{
public string? NextPageToken { get; set; }
public bool HasMoreResults { get; set; }
public int PageSize { get; set; } = 25;
public int CurrentPage { get; set; } = 1;
public Dictionary<int, string>? PageTokenHistory { get; set; }
public ViewType ViewType { get; set; } = ViewType.TailwindAndDaisy;
// Your actual data
public List<Product> Products { get; set; } = new();
}
此界面是最小的, 但功能强大的@ . @ Let' @%s 看看每个属性都做了些什么 @ MS K2 @ *
NextPageToken: 获取下一页的标记 @( 由您的数据库提供@)HasMoreResults:_Boolean 表示是否有更多页面PageSize: 每页的项目CurrentPage: 显示 - 仅用于 UI 的页面编号PageTokenHistory: 字典映射页面编号为用于后向导航的标记@ info: whatsthisViewType: CSS 框架用于提供
现在让我们来执行一个控制器动作, 模拟宇宙 DB\ - 风格的射程@ MS K2}
[Route("Products")]
public async Task<IActionResult> Products(
int currentPage = 1,
int pageSize = 25,
string? pageToken = null,
string? tokenHistory = null)
{
// Simulate fetching from Cosmos DB
var cosmosResults = await _cosmosService.GetProductsAsync(
pageSize: pageSize,
continuationToken: pageToken
);
// Deserialize token history for backward navigation
var history = string.IsNullOrEmpty(tokenHistory)
? new Dictionary<int, string>()
: JsonSerializer.Deserialize<Dictionary<int, string>>(tokenHistory)
?? new Dictionary<int, string>();
// Store current token in history
if (!string.IsNullOrEmpty(pageToken))
{
history[currentPage] = pageToken;
}
var viewModel = new ProductPagingViewModel
{
CurrentPage = currentPage,
PageSize = pageSize,
NextPageToken = cosmosResults.ContinuationToken,
HasMoreResults = cosmosResults.HasMoreResults,
PageTokenHistory = history,
Products = cosmosResults.Items
};
if (Request.IsHtmx())
{
return PartialView("_ProductList", viewModel);
}
return View(viewModel);
}
此功能显示象征历史如何允许后向导航@ . @ 没有它 @ MS K1 @ 继续象征性的外观只会支持 @ MPK2\ next"}按键=.}通过维护页面的字典 <-\to MSQK6}token 映射@,}我们既可以支持“ MSKO8” prepvied\ " ,也可以支持 &"_ nextñ"
这里“'”是象征性积累的可视化流 @:
sequenceDiagram
participant User
participant Controller
participant Database
participant TokenHistory
User->>Controller: Request Page 1 (no token)
Controller->>Database: Query with no token
Database-->>Controller: Data + Token_A
Controller->>TokenHistory: Store Token_A for page 1
Controller-->>User: Display Page 1
User->>Controller: Request Page 2 (Token_A)
Controller->>Database: Query with Token_A
Database-->>Controller: Data + Token_B
Controller->>TokenHistory: Add Token_B for page 2
Controller-->>User: Display Page 2
User->>Controller: Request Page 1 (retrieve from history)
Controller->>TokenHistory: Get Token for Page 1
Controller->>Database: Query with Token_A
Database-->>Controller: Data + Token_A
Controller-->>User: Display Page 1
在您的 Razor 视图中 @, @ 使用续序呼叫器简单@ : @
@model ProductPagingViewModel
<div id="product-container">
<table class="table">
<thead>
<tr>
<th>Product</th>
<th>Company</th>
<th>Price</th>
</tr>
</thead>
<tbody>
@foreach (var product in Model.Products)
{
<tr>
<td>@product.Name</td>
<td>@product.CompanyName</td>
<td>[email protected]("N2")</td>
</tr>
}
</tbody>
</table>
<continuation-pager
model="Model"
htmx-target="#product-container"
show-page-number="true"
show-pagesize="true" />
</div>
标签助手自动@: @%
- 将象征性历史序列化为查询参数
- 以合适的符号构建导航 URL
- 禁用%" @ preview@ "} 当页面@ I1 @
- 禁用@" @ next @ "}当
HasMoreResults是假的 - 保存所有其它查询参数@( @search=,}过滤器 @,}等{.)}
后向导航的脚本历史 @ {# @ token@ MS K1_ history @ MPK2 @
象征性历史方法的天才是,它“'”完全是可选的“MS K1” 如果你只需要 “"”Next‘"}导航“(’infinite pollic,” 例如“MSSK6}你就可以完全忽略象征性的历史:}*
<continuation-pager
model="Model"
enable-token-accumulation="false"
show-page-number="false" />
仅此设置一个没有页面指示器或历史管理的“"@ next @ "Q” 按钮@ MS K2@
对于完整导航 < , },象征性历史将自动序列化为 JSON 在查询字符串{. > 中的 JSonson 。\ MS K2 _ 这里>'_ URL 看上去像什么?
/Products?currentPage=3&pageSize=25&pageToken=abc123&tokenHistory=%7B%221%22%3A%22xyz789%22%2C%222%22%3A%22abc123%22%7D
缩略 tokenHistory 参数包含编码的字典@,}使后向导航无缝 *.
编号 导航 = {# 数 =\ MS K1 page} - Navigation =}
续用传呼器最重要的UX改进之一是 编号页面按钮@._Q}在您往前游时,请按下鼠标显示所有访问过的页面的可点击页码@:}
Initial page 1: [Next →]
After next click: [← Prev] [1] [2 active] [3 disabled] [Next →]
After next click: [← Prev] [1] [2] [3 active] [4 disabled] [Next →]
Click page 2: [← Prev] [1] [2 active] [3] [4 disabled] (no next - not visited yet)
这将提供传统的页码 UX, 同时维护 Sign@ - @ basim 后端架构@ I.} 每个被访问的页面的执行存储牌\ MS K2} 允许直接浏览先前访问过的任何网页@ MPK3}
限制历史增长+:
防止无约束内存使用@, @% 设置 max-history-pages @(_default :}20):#
<continuation-pager
model="Model"
max-history-pages="50"
show-page-number="true" />
当限制达到@,}最老的标牌自动缩略@ .}
查询参数保存 @{#Qquery @MS K2_parameter@-_preservation}
这是继续执行 pcalr 的最重要特点 @. @%
继续的符號只有使用相同的查詢上下文@ (_ filters\ @ MS K1}color , 搜尋)}來產生它們才有效 使用不同查詢參數的標籤會傳回不正確的数据或完全失敗%.}
继续 pager 自动保存所有查询参数, 除了它自己的@ : @
<!-- URL with filters -->
/Products?category=electronics&brand=acme&minPrice=100
<!-- After clicking Next -->
/Products?category=electronics&brand=acme&minPrice=100¤tPage=2&pageToken=xyz123&tokenHistory={...}
<!-- All filters preserved! Token is valid because query context matches. -->
如果需要, 您可以禁用此行为@ : @
<continuation-pager
model="Model"
preserve-query-parameters="false" />
但是,这是 强烈不鼓励 除非您% ' @ re绝对确定您的标牌don'@ t取决于查询的上下文@.}
为何如此重要?
宇宙 DB 示例*:
// Page 1 with filter
var query = container.GetItemQueryIterator<Product>(
"SELECT * FROM c WHERE c.category = 'electronics'",
continuationToken: null
);
var response = await query.ReadNextAsync();
// Returns: Products + Token_A
// Page 2 with SAME filter - Token_A is valid
var query2 = container.GetItemQueryIterator<Product>(
"SELECT * FROM c WHERE c.category = 'electronics'",
continuationToken: Token_A // ✅ Works!
);
// Page 2 with DIFFERENT filter - Token_A is invalid
var query3 = container.GetItemQueryIterator<Product>(
"SELECT * FROM c WHERE c.category = 'computers'",
continuationToken: Token_A // ❌ Wrong results or error!
);
继续 paller@ ' @%s 自动参数保存确保符号总是与原始查询上下文一起使用@.}
本地化支持 @
现代应用软件为全球受众服务 @, 且弹射控制器需要使用您的用户的语音@' 语言_. 版本#1.0.0 包括设置在库中的全面本地化支持}=.
以语言制作的{# -in- 语言=}
译为“8” 语言的图书馆船
-=YTET -伊甸园字幕组=- 翻译:
|------|----------|
| en |英语 @(}默认=)}|{
| de {\fn黑体\fs22\bord1\shad0\3aHBE\4aH00\fscx67\fscy66\2cHFFFFFF\3cH808080}
| es 西班牙语: ( ESPAñol MS K2 NSK3
| fr -=YTET -伊甸园字幕组=- 翻译:
| it |意大利语 @( @意大利语#)}@|
| pt 葡萄牙语: @( @Portuguès @)|#
| ja |日语 @()}#|日本语 @
| zh-Hans @|中文简化@()}#|
全部文本已本地化@ , @ 包括 @ MS K1} @
- 上一个@ / @ next @ / @ First @ MS K2 @ 最后一个按钮标签
- Z 项的简略文字\ (" 显示 X 到 Y+")\
- 无障碍的ARIA标签
- 页面大小标签 #% ("# 每页项目@")}
本地化系统由 .resx 资源文件@,使您能够轻松添加您的语言=%.}所有的资源文件都在 mostlylucid.pagingtaghelper/Resources/.
本地化使用量 @
使用本地化是直截了当的@. @ 只要添加 language 属性@: @%
<paging
model="Model"
language="de"
show-summary="true"
first-last-navigation="true" />
这将使所有文本都用 German :}( 德语) 成为文字
<!-- Previous button -->
<button>‹ Vorherige</button>
<!-- Summary -->
<div class="text-sm text-gray-600">
Zeige 1 bis 10 von 256 Einträgen
</div>
<!-- Next button -->
<button>Nächste ›</button>
对于基于用户首选项的动态语言切换 <% , 设置您的控制器中的语言\ MS K1\
public async Task<IActionResult> Products(
int page = 1,
int pageSize = 10,
string language = "en")
{
var pagingModel = await GenerateModel(page, pageSize);
ViewBag.SelectedLanguage = language;
return View(pagingModel);
}
然后在您看来“, ” 创建一个语言选择器@:
@{
var selectedLanguage = ViewBag.SelectedLanguage as string ?? "en";
var languages = new Dictionary<string, string>
{
{ "en", "English" },
{ "de", "German" },
{ "es", "Spanish" },
{ "fr", "French" },
{ "it", "Italian" },
{ "pt", "Portuguese" },
{ "ja", "Japanese" },
{ "zh-Hans", "Chinese" }
};
}
<select onchange="window.location.href='/Products?language=' + this.value">
@foreach (var lang in languages)
{
<option value="@lang.Key" selected="@(lang.Key == selectedLanguage)">
@lang.Value
</option>
}
</select>
<paging
model="Model"
language="@selectedLanguage"
link-url="/Products" />
您也可以在其它元素本地化的好处中, 覆盖单个文本字符串@: @% 1
<paging
model="Model"
language="ja"
previous-page-text="戻る"
next-page-text="次へ"
summary-template="全{TotalItems}件中 {StartItem}~{EndItem}件を表示" />
缩略 PagingLocalizer 如果您通过了无效语言代码@,}它会自然地返回到英语\ .}
对于 HTMX 整合 < , } 你'\ {将希望保存所有请求中的语言\ MS K2\ *
<script>
htmx.on('htmx:configRequest', function(event) {
if (event.detail.path.includes('/Products')) {
event.detail.parameters.language = '@selectedLanguage';
}
});
</script>
这样可以确保 HTMX 部分视图更新保持所选语言@.
JavaScript 模式 @ {# @ javastricte@ MS K1_ modes @ MPK2 @
V1.0.0中最重要的改进之一是引入了灵活的 JavaScript 模式@ . 前情提要 @ MS K2你有一个布林选择@: use-htmx="true" 或 use-htmx="false". 现在您有五种不同的模式 @, 每种都为不同情景优化了=.
可用的模式 @ {# @ option\ MS K1 @ modes@ } @
下面是 JavaScript 模式的完整解析@: @
graph TD
A[JavaScript Modes] --> B[HTMX]
A --> C[HTMXWithAlpine]
A --> D[Alpine]
A --> E[PlainJS]
A --> F[NoJS]
B --> B1[Uses HTMX for partial updates]
B --> B2[hx-get, hx-target, hx-swap]
C --> C1[HTMX + Alpine.js directives]
C --> C2[Enhanced interactivity]
D --> D1[Pure Alpine.js]
D --> D2[x-data, @click handlers]
E --> E1[Vanilla JavaScript]
E --> E2[onclick handlers]
F --> F1[Zero JavaScript]
F --> F2[Standard anchor links & forms]
让我们在动作中看到每个模式@ : @
1.#HTMX 模式 @(_Default})
<paging
model="Model"
js-mode="HTMX"
htmx-target="#results-container" />
重新命名@: @
<button hx-get="/Products?page=2" hx-target="#results-container" hx-swap="outerHTML">
Next ›
</button>
这是现代 ASP=.}NET Core applications.}推荐的模式
2.HTMX与阿尔卑斯山模式
<paging
model="Model"
js-mode="HTMXWithAlpine"
htmx-target="#results-container" />
重新命名@: @
<button
x-data
hx-get="/Products?page=2"
hx-target="#results-container"
hx-swap="outerHTML">
Next ›
</button>
与 Alpine 组合用于导航的 HTMX 和 Alpino @ . @ jjs 以附加客户端@ MS K1} 侧面交互性\ .} 当您需要反应式 UI 元素时, 请使用此选项。
3.高山模式
<paging
model="Model"
js-mode="Alpine" />
重新命名@: @
<button
x-data
@click="window.location.href = '/Products?page=2'">
Next ›
</button>
纯Alpine.js 没有 HTMXMS K1}有用 当您已经使用 Alpine}.Js 但不要HTMX依赖性时
@ 4. 普通JS 模式
<paging
model="Model"
js-mode="PlainJS" />
重新命名@: @
<button onclick="window.location.href = '/Products?page=2'">
Next ›
</button>
没有框架依赖性@, 仅是 Vanilla JavaScript @. 此模式还包括一个用于更改页面大小的助手@ :}
@Html.PageSizeOnchangeSnippet()
这将输入所需的 JavaScript , 用于在不使用 HTMX @ . 的情况下处理页面大小下调更改
5. noJS 模式
<paging
model="Model"
js-mode="NoJS" />
重新命名@: @
<!-- Navigation uses standard anchor links -->
<a href="/Products?page=2">Next ›</a>
<!-- Page size uses a form with submit button -->
<form method="get" action="/Products">
<input type="hidden" name="page" value="1" />
<select name="pageSize" onchange="this.form.submit()">
<option value="10">10</option>
<option value="25" selected>25</option>
<option value="50">50</option>
</select>
<noscript>
<button type="submit">Update</button>
</noscript>
</form>
零 JavaScript 需要@. @sperfect
- 无障碍要求
- 渐进增强设想方案
- JavaScript 禁用的环境
- SEO-}关键頁面,您希望在哪里爬行? -}#方便的导航
这个体系的美丽之处在于 所有模式都保存您现有的查询参数. 您是否通过分类@ MS K2 搜索 @ , 或排序@ I, 您的状态自动维持@ MPK5
从使用移民@-ñáhtmx @
后向兼容性=,旧 use-htmx 仍在工作属性@: @%
<!-- Old syntax (still works) -->
<paging model="Model" use-htmx="true" />
<!-- Equivalent to js-mode="HTMX" -->
<paging model="Model" use-htmx="false" />
<!-- Equivalent to js-mode="PlainJS" -->
但我建议移居到新的世界 js-mode 清晰度属性@: @%
<!-- New syntax (recommended) -->
<paging model="Model" js-mode="HTMX" />
<paging model="Model" js-mode="PlainJS" />
视图类型增强@ {# @ viewtype @ MS K1_ enhancements @ MPK2
版本 @1.0.0 引入了两个重要的 ViewType 添加内容, 涉及常见真实@-}世界情景.
纯粹的尾风 @ {# @ pure@ MS K1} 尾风+}
前情提要 , 如果你想要尾风 CSCS的打字,你得到了 TailwindAndDaisy 使用 DaisiUI 组件的视图@ . @ 如果您已经使用了 DasiUI @ MS K2} 这将非常棒, 如果您想要纯尾风而不使用 DsaisyUI Appliance\ ?
输入 ViewType.Tailwind:
<paging
model="Model"
view-type="Tailwind" />
这样只能使用标准的尾风工具类@ : @ {
<div class="flex gap-2 items-center">
<button class="px-4 py-2 text-sm font-medium rounded-md bg-blue-600 text-white hover:bg-blue-700">
‹ Previous
</button>
<div class="px-3 py-1 text-sm font-medium bg-gray-100 dark:bg-gray-700 dark:text-white rounded-md">
Page 1
</div>
<button class="px-4 py-2 text-sm font-medium rounded-md bg-blue-600 text-white hover:bg-blue-700">
Next ›
</button>
</div>
否 无 btn, badge,或 join @ – @ just pleaty Talkwind@ MS K1}这样您就可以完全控制无组成部分库依赖关系的外观设置
比较:
| ViewType | CSS框架 * | 组件库* | 使用 case= | |
|---|---|---|---|---|
TailwindAndDaisy 已经使用 DaisyUI & |
的工程 | |||
Tailwind |
+TackwindCSCS+ | +None @ | +纯斜尾风工程@ | # |
Bootstrap |
_Bootstract { | }布设构件 @ | _Botscrap Projects { | {poststractions project {possible_BARBAR_ posities_B拉皮条系构件@MSK4_BRATIONBLA} MS K3} |
Plain |
嵌入式 CSS | 无 @ | 没有框架依赖性 * | |
NoJS -=YTET -伊甸园字幕组=- 翻译: |
NoJS 模式 @
缩略 NoJS ViewType 组合零 JavaScript 和普通 CSS 样式@ :
<paging
model="Model"
view-type="NoJS"
show-pagesize="true" />
与其他视图类型的密钥差异@: @%
- 导航使用锁定链接# ,# 不是按钮 @:#
<a href="/Products?page=2" class="pager-button">Next ›</a>
- 页面大小选择器是一个窗体:
<form method="get" action="/Products" class="page-size-form">
<!-- Preserves all current query parameters as hidden inputs -->
<input type="hidden" name="search" value="laptop" />
<input type="hidden" name="category" value="electronics" />
<!-- Reset to page 1 when changing page size -->
<input type="hidden" name="page" value="1" />
<label for="pageSize">Items per page:</label>
<select name="pageSize" onchange="this.form.submit()">
<option value="10">10</option>
<option value="25" selected>25</option>
<option value="50">50</option>
</select>
<!-- Button visible when JavaScript is disabled -->
<noscript>
<button type="submit" class="page-size-button">Update</button>
</noscript>
</form>
缩略 onchange="this.form.submit()" 当 JavaScript 有时提供方便@ , @ but the <noscript> 按钮在它“% '” 而非“ MS K1” 时确保完整功能
URL 参数保存@{# @url-_parameter @-}preservation*}
在 page@.}版本 @1.0.0 解决此优雅方式时, 您的过滤器@ ,搜索术语\ , 或排序顺序已丢失。 自动保存所有查询参数, 除了弹射控制@' @%s 自己的参数.
此特性在 正常的呼叫器和继续的按键# ,和横跨# 全部 JavaScript 模式和视图类型.
这里#' @%_ 如何在内部工作@:} @
string BuildQueryString(string? token, int page)
{
var query = new Dictionary<string, string>();
// Define continuation pager's own parameters that should be excluded from preservation
var pagerParams = new HashSet<string>(StringComparer.OrdinalIgnoreCase)
{
"pageSize", "currentPage", "pageToken", "tokenHistory"
};
// Add parameter prefix variants if using prefixed parameters
if (!string.IsNullOrEmpty(Model.ParameterPrefix))
{
pagerParams.Add($"{Model.ParameterPrefix}_pageSize");
pagerParams.Add($"{Model.ParameterPrefix}_currentPage");
pagerParams.Add($"{Model.ParameterPrefix}_pageToken");
pagerParams.Add($"{Model.ParameterPrefix}_tokenHistory");
}
// Preserve all existing query parameters (except pager's own) if enabled
if (Model.PreserveQueryParameters)
{
foreach (var param in ViewContext.HttpContext.Request.Query)
{
if (!pagerParams.Contains(param.Key))
{
query[param.Key] = param.Value.ToString();
}
}
}
// Add continuation pager parameters (with prefix if specified)
var pageSizeParam = Model.GetParameterName("pageSize");
var currentPageParam = Model.GetParameterName("currentPage");
var pageTokenParam = Model.GetParameterName("pageToken");
var tokenHistoryParam = Model.GetParameterName("tokenHistory");
query[pageSizeParam] = pageSize.ToString();
query[currentPageParam] = page.ToString();
if (!string.IsNullOrEmpty(token))
query[pageTokenParam] = token;
if (Model.EnableTokenAccumulation)
query[tokenHistoryParam] = tokenHistoryJson;
return string.Join("&", query.Select(kvp =>
$"{Uri.EscapeDataString(kvp.Key)}={Uri.EscapeDataString(kvp.Value)}"));
}
此方法意指:
*假想 {1:} 搜索 \ +} 挂接
Initial URL: /Products?search=laptop&category=electronics&page=1
Click Next: /Products?search=laptop&category=electronics&page=2
Change Page Size: /Products?search=laptop&category=electronics&page=1&pageSize=50
正在排序 _+ pignation
Initial URL: /Products?orderBy=price&descending=true&page=1
Click Page 3: /Products?orderBy=price&descending=true&page=3
带有过滤器的“ 3:” 继续打印程序
Initial URL: /Products?category=electronics&brand=acme
Click Next: /Products?category=electronics&brand=acme¤tPage=2&pageToken=abc123&tokenHistory={...}
在 {(} noJS mode ). 表格中相同的保存工作 当转换页面大小的窗体,} 视图自动包含所有非{MS K3 pagination 参数的隐藏输入@:}
<form method="get" action="@linkUrl" class="page-size-form">
@* Preserve all existing query parameters except pageSize and page-related ones *@
@foreach (var param in ViewContext.HttpContext.Request.Query)
{
if (!new[] { "pageSize", "currentPage", "pageToken", "tokenHistory" }
.Contains(param.Key, StringComparer.OrdinalIgnoreCase))
{
<input type="hidden" name="@param.Key" value="@param.Value" />
}
}
@* Reset to page 1 when changing page size *@
<input type="hidden" name="currentPage" value="1" />
<select name="pageSize" onchange="this.form.submit()">
<!-- options -->
</select>
</form>
这工作无缝地顺利 全部 JavaScript 模式和所有视图类型. 您不必手动管理查询字符串传播@.
《移民指南》{# migration_ -_ Guide MSSK2
升级前的“-1.0”版本是直截了当的@,}但有一些断裂的更改, 以了解 @.
断开更改
1. use-htmx 还在工作 )
旧的:
<paging model="Model" use-htmx="true" />
<paging model="Model" use-htmx="false" />
新建 ( 推荐@): @
<paging model="Model" js-mode="HTMX" />
<paging model="Model" js-mode="PlainJS" />
2.ViewType.TaillwindandDaisy 现在使用完整的 DisaiUI 组件
如果你使用 ViewType.TailwindAndDaisy 想要纯粹的尾风 没有DaisiU:
旧行为 @ ( @ 纯白尾风@ MS K1 @
<paging model="Model" view-type="TailwindAndDaisy" />
新的“(”以获得旧行为@):
<paging model="Model" view-type="Tailwind" />
继续使用 TailwindAndDaisy 如果您使用 DaisiUI 元件@ :
<paging model="Model" view-type="TailwindAndDaisy" />
<!-- Uses btn, join, badge, select, etc. -->
3.HTMX升级为2.0.4
如果您在应用程序中其他地方使用 HTMX , @,}确保与 HTM X 的兼容性@2.0.4.}大多数HTMX\ 1.x 代码正常工作。 HTMX 2.0移民指南 用于边缘情况@. @%
斯捷步-B-Step移徙
步骤 @1:}更新 NuGet 软件包
dotnet add package mostlylucid.pagingtaghelper --version 1.0.0
步骤“2:”审查您现有的代码
搜索您的代码库 use-htmx 属性@: @%
# PowerShell
Get-ChildItem -Recurse -Include *.cshtml | Select-String "use-htmx"
# Bash/Git Bash
grep -r "use-htmx" --include="*.cshtml" .
步骤“3:”更新到js- mode @(_建议@)}
替换 use-htmx 与 js-mode:
- <paging model="Model" use-htmx="true" htmx-target="#results" />
+ <paging model="Model" js-mode="HTMX" htmx-target="#results" />
- <paging model="Model" use-htmx="false" />
+ <paging model="Model" js-mode="PlainJS" />
4: 校验尾风和Daisy的使用情况
如果您没有安装 DaisaiUI , 但正在使用 TailwindAndDaisy:
- <paging model="Model" view-type="TailwindAndDaisy" />
+ <paging model="Model" view-type="Tailwind" />
步骤 @5:_# 彻底测试
运行您的应用程序并测试@: @%
- 页面导航
- 页面大小变化
- HTMX 部分更新@(if 使用HTMX @)
- 过滤器/搜索保护
- 移动响应
要通过的新特点
一旦迁移 , 考虑采用这些新功能 :
本地化@: @%
<paging
model="Model"
language="@CultureInfo.CurrentUICulture.TwoLetterISOLanguageName" />
使用 NOSQL): 来继续 Pager @ ( @ if
<continuation-pager
model="Model"
htmx-target="#results-container"
show-page-number="true" />
NoJS 模式@( @ for access
<paging model="Model" js-mode="NoJS" />
Dema 应用程序@{# @demo-}应用程序_}
图书馆包含一个全面的演示应用程序,显示所有功能@. 您可以在本地运行或查看 演示站点 即将到来
正在运行本地端的 Demo @ : @
git clone https://github.com/scottgal/mostlylucid.pagingtaghelper.git
cd mostlylucid.pagingtaghelper/mostlylucid.pagingtaghelper.sample
dotnet run
导航至 https://localhost:5001 来探索 @:
- 与模型基本对接 - 传统 SQL- 风格传呼
- HTMX 整合 - 动态页面更新, 没有全页重新加载
- 使用 HTMX 搜索 *- 联合搜索和射程
- 普通 CSS -无框架依赖性
- 纯粹尾风 - 尾风 CSS 没有DisaiUI
- 无 JavaScript -=YTET -伊甸园字幕组=- 翻译:
- JavaScript 模式 所有五种联署材料模式都展示了侧面的“-”和“MS K2”
- 页面排序 - 带有 HTMX 的可排序信头
- 页面排序无 HTMX - 具有全页负载的可排序信头
- 带有 HTMX 的页面大小 - 动态页面大小变化
- 页面大小无 HTMX - 页面大小及表格提交
- 继续页面器 -NoSQL- 风格牌 *-基底射程
- 本地化 - 语言选择器
每个演示包含 @: @%
- 工作源代码
- 技术解释
- 与 GitHub 执行链接
- 用于实验的交互式控件
结论结论
版本“1.0.0”是PagingTagHelfer图书馆的重要里程碑。 “简单的工作要求”始于此,现已演变成一个综合性的“MS K2”制片“--备妥的射程解决方案,可以处理 @: }
- 传统SQL页数 页:1
- NOSQL 继续代号显示 对于宇宙 DB ,DynamoDB,等
- 多语种本地化 供全球受众使用
- 弹性 JavaScript 模式 从 HTMX 到零@ - @ JavaScript
- CSS 多个多 CSS框架 从DisaiUI 到纯尾风到无
- 智能参数保护 横贯所有导航
- 完全无障碍支持 带有 ARIA 标签和键盘导航
该图书馆已经通过“1.7Qk+下载”测试并准备投入生产使用。 “.}所有 106单位测试都通过了@,,综合演示应用展示显示真实的#-world用法模式*.
什么是' 下一步 @?
未来增强功能 I'm考虑}MS K1
- 附加的 CSS 框架支持 @ ( @ matirial UIQ,} Bulma)
- 更多本地化语言 @(#社区捐款欢迎@!)_%
- Server -side Blazor 元件
- 增强无障碍环境特点
- 大型数据集的性能优化
开始
通过 Nuget @ :+% 安裝
dotnet add package mostlylucid.pagingtaghelper --version 1.0.0
检查文档@: @%
在 GitHub 上打开一个问题, -=YTET -伊甸园字幕组=- 翻译:.
玩得开心吗?