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.
Wednesday, 23 April 2025
//Less than a minute
في ما يصبح سلسلة، في مشروع عمل أردت أن أضيف القدرة على جزئية إلى التحديث التلقائي على مقياس زمني معين.
هذه هي الطريقة التي فعلت ذلك باستخدام الألبين.ج و HTMX.
لذلك اردت ان يكون هذا
ومع وضع هذا في الاعتبار، شرعت في بناء وحدة صغيرة من طراز JS باستخدام Alpine.js و HTMX.
يمكنك القيام بتحديثات تلقائية للمميزات 'على و خارج' و'تذكر' ببساطة مع HTMX وحده. على سبيل المثال؛ على سبيل المثال؛ HTMKXXXX مُززززززز يمكنك حقا القيام بالكثير من الأشياء.
<div id="campaignemail-request-list" hx-get="@Url.Action("List", "CampaignEmailRequest")" hx-trigger="every 30s" hx-swap="innerHTML">
<partial name="_List" model="@Model"/>
</div>
هذا الرمز يستخدم في الواقع hx-trigger
لضبط الاستكمال التلقائي. فقط باستخدام Alpin.js لضبط خواص HTMX.
ما يضيفه هذا حقاً هو جانب تفاعل المستخدم مع العميل، وهو ما تجيده الألبين.js.
رمز هذا هو حقاً مدمجة جداً، انها مقسمة إلى جزأين رئيسيين، وحدة JS، معالجي الأحداث و HTML.
وهذه النميطة عبارة عن نميطة بسيطة من النميطة المشتركة تستخدم الألبينية (Alpin.js) لإدارة حالة التحديث الذاتي. وهي تستخدم التخزين المحلي لتذكر حالة التحديث التلقائي بين الطلبات.
« إن » ما « هي » أي ما « هي ».
endpointId
- هوية العنصر المراد تحديثهactionUrl
- أورل الذي سيُستدعى لتحديث العنصر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()
الموهذا الأسلوب يمكّن أو يعطل تلقائياً من توجيه عنصر HTML المستهدف باستخدام HTMX.
endpointId
.fullUrl
بالجمع بين ما يلي : actionUrl
مع الحالي سطر.localStorage
(جيد كما يُذكر بين جلسات المتصفح).this.autoUpdate
هو true
(أي، يُمكَّن الاقتراع من القيام بما يلي:hx-trigger
إلى أن تُعلَل interval
ثانياًhx-swap="innerHTML"
بدلاً من الاستعاضة عن محتوى العنصرhx-get
إلى المُلْزِل UR URhx-headers
"AutoPoll": "auto"
localStorage
htmx.process(el)
إلى السماح HTMX 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'}
});
}
هذا الدالة a HTMX طلب إلى fullUrl
ويستكمل عنصر الهدف مع الرد. هذا مفيد لعرض المستخدم كيف سيبدو التحديث التلقائي عند تمكينه.
أنت سَتُلاحظُ بأنّنا نُرسلُ أيضاً a HTMX ترويسة مع الطلبِ. هذا مهم لأنه يسمح لنا باكتشاف جانب خادم الطلب.
el.setAttribute('hx-headers', JSON.stringify({ AutoPoll: 'auto' }));
headers: {AutoPoll: 'auto'}
في جانب خادمي I ثم الكشف عن هذا الترويض الذي يجري تشغيله
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 _)
وإذا كان هناك أعرف أنه طلب تلقائي
ثم آخذ الييمي الحالي (إنه لعميل فرنسي، لذا أتحول إلى وقت باريس) وأعرض نخباً مع الوقت.
الـ 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:
لجعل هذا صغير و قابل لإعادة الاستخدام قدر الإمكان شفرة الرازر بسيطة جدا.
يمكنك أن ترى هنا أنا تحديد بيانات Alpene.js إلى setet uniti- update.
سترون أننا حددنا الهدف لاستخدامه من أجل الطلب إلى campaignemail-request-list
(ج) عنصر من العنصر أو العنصر أو العنصر أو العنصر أو العنصر أو العنصر أو العنصر أو العنصر أو العنصر أو العنصر أو العنصر أو العنصر أو العنصر أو العنصر أو العنصر أو العنصر أو العنصر أو العنصر أو العنصر أو العنصر. هذا هو العنصر الذي سيتم تحديثه مع المحتوى الجديد.
وهذا بعد ذلك يتضمن بعض الأشياء في الصفحة.
الآن متى a كشّير مربّع هو مؤكّد الإيطالية تحديث قائمة.
<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>
وهذا هو عليه، الحق بسيط جدا. Leeding HTMX و Alpin.js لإنشاء عنصر تحديث تلقائي بسيط يمكننا استخدامه بسهولة من ASP.NET الأساسية.