This is a viewer only at the moment see the article on how this works.
To update the preview hit Ctrl-Alt-R (or ⌘-Alt-R on Mac) or Enter to refresh. The Save icon lets you save the markdown file to disk
This is a preview from the server running through my markdig pipeline
所以在一系列的系列中,在一个工作项目中, 我想增加部分能力, 以自动更新特定的时间尺度。
这是我用阿尔卑斯山和HTMX做的
所以我希望这个
考虑到这一点,我准备用阿尔卑斯山和HTMX建立一个小型的联署材料模块。
您可以用自动更新“ 运行和关闭” 和“ 记住” 功能, 只需使用 HTMX 即可 。 例如; 例如; 使用 HTMX 触发器 你真的可以做很多事情。
<div id="campaignemail-request-list" hx-get="@Url.Action("List", "CampaignEmailRequest")" hx-trigger="every 30s" hx-swap="innerHTML">
<partial name="_List" model="@Model"/>
</div>
感谢 @KhalidAbuhakmeh 写道: 指出这一点。
此代码实际上确实使用此代码 hx-trigger
设置自动更新。 使用 Alpine.js 配置 HTMX 属性。
这真正增加的是用户互动客户端;这就是阿尔卑斯山的伟大之处。
这个代码非常紧凑, 分为两个主要部分: JS模块,事件处理者和 HTML。
该模块是一个简单的联署材料模块,使用Alpine.js管理自动更新状态。 它使用本地存储系统来记起在两次请求之间自动更新的状态。
它接受以下参数:
endpointId
- 需要更新的内容的代号actionUrl
- 需要调用URL来更新元素initialInterval
- 自动更新所使用的初始间隔(默认为 30 秒)我们还可以看到它使用几个密钥;这些密钥用于当地的存储,以便记住自动更新的状态。
你可以看到我用的是 actionurl
作为使这一终点具体化的关键部分。
export function autoUpdateController(endpointId, actionUrl, initialInterval = 30) {
const keyPrefix = `autoUpdate:${actionUrl}`;
const enabledKey = `${keyPrefix}:enabled`;
return {
autoUpdate: false,
interval: initialInterval,
toggleAutoUpdate() {
const el = document.getElementById(endpointId);
if (!el) return;
const url = new URL(window.location.href);
const query = url.searchParams.toString();
const fullUrl = query ? `${actionUrl}?${query}` : actionUrl;
const wasPreviouslyEnabled = localStorage.getItem(enabledKey) === 'true';
if (this.autoUpdate) {
el.setAttribute('hx-trigger', `every ${this.interval}s`);
el.setAttribute('hx-swap', 'innerHTML');
el.setAttribute('hx-get', fullUrl);
el.setAttribute('hx-headers', JSON.stringify({ AutoPoll: 'auto' }));
localStorage.setItem(enabledKey, 'true');
htmx.process(el); // rebind with updated attributes
if (!wasPreviouslyEnabled) {
htmx.ajax('GET', fullUrl, {
target: el,
swap: 'innerHTML',
headers: {AutoPoll: 'auto'}
});
}
} else {
el.removeAttribute('hx-trigger');
el.removeAttribute('hx-get');
el.removeAttribute('hx-swap');
el.removeAttribute('hx-headers');
localStorage.removeItem(enabledKey);
htmx.process(el);
}
},
init() {
this.autoUpdate = localStorage.getItem(enabledKey) === 'true';
this.toggleAutoUpdate();
}
};
}
toggleAutoUpdate()
方法方法方法此方法能够或禁用使用 HTMX 对目标 HTML 元素进行自动投票 。
endpointId
.fullUrl
合并给定的 actionUrl
使用当前页面的查询字符串。localStorage
(在浏览器会话之间可以记住)this.autoUpdate
是 true
(即使投票得以进行):hx-trigger
民意调查 interval
秒数秒hx-swap="innerHTML"
替换元素的内容hx-get
指向投票 URLhx-headers
添加自定义 "AutoPoll": "auto"
标题标题标题localStorage
htmx.process(el)
使 HTMX 识别新属性htmx.ajax()
(不依赖 HTMX 事件电线)this.autoUpdate
是 false
(即投票有残疾):localStorage
htmx.process(el)
以再次更新 HTMX 行为我们这里还有一个分行 第一次启用自动投币时执行自动投币
const wasPreviouslyEnabled = localStorage.getItem(enabledKey) === 'true';
if (!wasPreviouslyEnabled) {
htmx.ajax('GET', fullUrl, {
target: el,
swap: 'innerHTML',
headers: {AutoPoll: 'auto'}
});
}
执行 HTMX 向 fullUrl
并根据回应更新目标要素。 用于显示用户在启用时自动更新的外观 。
你将会注意到,我们也发送一个HTMX信头 与请求。 这一点很重要,因为它使我们能够检测请求服务器的侧面。
el.setAttribute('hx-headers', JSON.stringify({ AutoPoll: 'auto' }));
headers: {AutoPoll: 'auto'}
在我的服务器侧端, 我检测到这个信头是使用
if (Request.Headers.TryGetValue("AutoPoll", out _))
{
var utcDate = DateTime.UtcNow;
var parisTz = TimeZoneInfo.FindSystemTimeZoneById("Europe/Paris");
var parisTime = TimeZoneInfo.ConvertTimeFromUtc(utcDate, parisTz);
var timeStr = parisTime.ToString("yyyy-MM-dd HH:mm:ss");
Response.ShowToast($"Auto Update Last updated: {timeStr} (paris)",true);
return PartialView("_List", requests);
}
你等着瞧,我只要找找头头和 Request.Headers.TryGetValue("AutoPoll", out _)
如果它在那里,我知道 这是一个自动投票请求。
然后拿下现在的 Yime (这是给法国客户的, 所以我改换巴黎时间) 并用时间举杯祝酒。
缩略 ShowToast
方法是一种简单的扩展方法,它设定一个触发器,让 HTMX 显示一个敬杯信息。
public static void ShowToast(this HttpResponse response, string message, bool success = true)
{
response.Headers.Append("HX-Trigger", JsonSerializer.Serialize(new
{
showToast = new
{
toast = message,
issuccess =success
}
}));
}
然后通过我的HTMX吐司组件 检测到它 显示信息。
document.body.addEventListener("showToast", (event) => {
const { toast, issuccess } = event.detail || {};
const type = issuccess === false ? 'error' : 'success';
showToast(toast || 'Done!', 3000, type);
});
然后,这需要我的吐司构成部分一。 在此写入 .
将这个模块连接起来非常简单, 在您的主,js\ index.js 中,不管什么只是导入它,然后把它连接到窗口
import './auto-actions';
window.autoUpdateController = autoUpdateController; //note this isn't strictly necessary but it makes it easier to use in the HTML
//Where we actually hook it up to Alpine.js
document.addEventListener('alpine:init', () => {
Alpine.data('autoUpdate', function () {
const endpointId = this.$el.dataset.endpointId;
const actionUrl = this.$el.dataset.actionUrl;
const interval = parseInt(this.$el.dataset.interval || '30', 10); // default to 30s
return autoUpdateController(endpointId, actionUrl, interval);
});
});
然后我们调用ASP.NET Razor代码中的Init方法:
尽可能小的和可以重复使用 剃刀代码很简单
您可以在这里看到, 我指定了 Alpine.js 数据属性来设置自动更新 。
你会看到我们设定了目标 用于请求 campaignemail-request-list
元素。 此元素将随新内容更新 。
然后在页面上包括了某个地方。
当选中一个复选框时, 它会自动每30秒更新一次列表 。
<div class=" px-4 py-2 bg-base-100 border border-base-300 rounded-box"
x-data="autoUpdate()"
x-init="init"
x-on:change="toggleAutoUpdate"
data-endpoint-id="campaignemail-request-list"
data-action-url="@Url.Action("List", "CampaignEmailRequest")"
data-interval="30"
>
<label class="flex items-center gap-2">
<input type="checkbox" x-model="autoUpdate" class="toggle toggle-sm" />
<span class="label-text">
Auto update every <span x-text="$data.interval"></span>s
</span>
</label>
</div>
<!-- Voucher List -->
<div id="campaignemail-request-container">
<div
id="campaignemail-request-list">
<partial name="_List" model="@Model"/>
</div>
</div>
就是这样,非常简单的权利。 利用 HTMX 和 Alpine.js 创建一个简单的自动更新组件, 我们很容易从 ASP. NET Core 中使用 。