جولة شاملة من توسيعات HTMX واستخدام HTMX مع ASP.net (العربية (Arabic))

جولة شاملة من توسيعات HTMX واستخدام HTMX مع ASP.net

Friday, 02 May 2025

//

17 minute read

أولاً

HTMX هي مكتبة جافاسكربت قوية تسمح لك بإنشاء تطبيقات ويب ديناميكية بحد أدنى جافاسكربت. تمكنك من جعل طلبات AJAX، مبادلة محتوى HTML، والتعامل مباشرة مع الأحداث في خصائص HTML. لقد كنت أستخدم HTMX لمدة عامين تقريبا في هذه النقطة ومع كل مشروع أتعلم المزيد والمزيد عن قدراته، والأهم من ذلك هو حدوده.

ومع ذلك لا زلت لا أدعي أن لدي معرفة خبيرة بها، أردت فقط أن أشارككم بعض الأشياء التي تعلمتها على طول الطريق.

المادة المصاحبة: تركز هذه المادة على نظام الأحداث الخاص بـ HTMX وامتداداتها وتكييفها المتقدم. بالنسبة لـ ASP.NET أنماط التكامل الأساسية مع وجهات نظر جزئية، HTMX.NET، والملحق، انظر مقالتي المرافقة: HTMX مع ASP.net.

أحداث أحداث

طلب

مرحلة إعداد الطلب هي المكان الذي يقوم فيه HTMX بتجهيز الطلب قبل إرساله إلى الخادوم. وهذا يشمل تحديد الترويسة، وإضافة البارامترات، ومعالجة إدخالات المستخدم. يتم تشغيل الأحداث التالية أثناء هذه المرحلة:

flowchart LR

        A[htmx:configRequest] --> B[htmx:confirm] --> C[htmx:prompt] --> D[htmx:abort]

دورة حياة

مرحلة دورة حياة الطلب هي حيث يرسل HTMX الطلب إلى الخادم ويعالج الرد. يتم تشغيل الأحداث التالية خلال هذه المرحلة:

flowchart LR
 E[htmx:beforeRequest] --> F[htmx:request] --> G[htmx:afterRequest]

مرحلة مناولة الاستجابة هي حيث يقوم HTMX بتجهيز الاستجابة من الخادوم وتحديث DOM. يتم إطلاق الأحداث التالية خلال هذه المرحلة:

flowchart LR
        H[htmx:beforeOnLoad] --> I[htmx:onLoad]
        I --> J[htmx:beforeSwap] --> K[htmx:swap] --> L[htmx:afterSwap]
        L --> M[htmx:afterSettle] --> N[htmx:afterOnLoad]

تَدِِِِِِِِِِِِِِْْْْْْْْْْْْْْْْْْْْْْْْْْ

مرحلة إدارة التاريخ هي حيث يقوم HTMX بتحديث تاريخ و عنوان المتصفح. الأحداث التالية تبدأ خلال هذه المرحلة:

flowchart LR
 A[htmx:historyRestoreRequest]
 A --> B[htmx:historyPopped]
 B --> C[htmx:historyRestorePage]

كما ترون HTMX يوفر عدد من الأحداث التي يمكنك ربطها لتعديل الطلب أو الاستجابة، أو حتى التاريخ؛ يقوم HTMX بعمل LOT لكونه نظاماً مدمجاً. باستخدام كل واحد من هذه يمكنك تعديل كيفية تفاعل HTMX مع الخادم/ العميل بطرق شاملة جداً.

المُذْكِِِِِِِِِِِِِِ المِِِِِِِِِِِِِِ المِِِِِِِِِِ

أحد أقوى جوانب HTMX هو القدرة على & مُرسِل في حالتي، أنا عادةً أرتبط في htmx:configRequest إضافة إلى طلب هذا هو إلى تمرير إضافي بيانات إلى خادم بدون إلى تعديل HTML أو جافاScript code.

تمديدات أخرى أخرى قد تكون خطاطا htmx:beforeRequest (أ) تعديل الطلب قبل إرساله؛ ما بعد مـن مـن مـن مـن مـن مـن مـن مـن مـن مـن مـن مـن مـن مـن مـن مـن مـن مـن مـن مـن configRequestلـك في beforeRequest (أ) مثل: HX-Vals وقد عقد مؤتمراً بشأن HX-Includes مُرفقة مسبقاً بإعادة النشوء (إما في الحمولة / الإستشارة). يمكنك حتى أن تُخطِط htmx:afterSwap لأداء الأفعال بعد تبديل المحتوى. مع الجمع مع جانب العميل الذي يقوم بتبديل المكتبات مثل: الألابين أو ليت لتر يمكنك إنشاء تطبيقات ديناميكية قوية مع الحد الأدنى من الشفرة.

HTMX يوفر بعض الامتدادات المثبتة مثل hx-boost وقد عقد مؤتمراً بشأن hx-swap-oob تسمح لك بتعزيز وظيفة HTMX دون كتابة أي رمز مخصص. لكن هناك أوقات تحتاج فيها إلى إنشاء تمديدات خاصة بك لتلبية متطلبات محددة.

على سبيل المثال، قد ترغب في إضافة ترويسات مخصصة إلى طلباتك، أو تعديل حمولة الطلب، أو التعامل مع أحداث محددة بطريقة فريدة.

لتحقيق هذا HTMX يوفر لكم بعض نقاط التكامل المفيدة:


{
  /**
   * init(api)
   * Called once when the extension is initialized.
   * Use it to set up internal state, store references, or access HTMX utility functions via the api parameter.
   */
  init: function(api) {
    return null;
  },

  /**
   * getSelectors()
   * Returns additional CSS selectors that HTMX should monitor.
   * Useful if your extension needs to handle custom elements or dynamic behavior.
   */
  getSelectors: function() {
    return null;
  },

  /**
   * onEvent(name, evt)
   * Called on every HTMX event (e.g., htmx:beforeRequest, htmx:afterSwap).
   * Return false to cancel the event or stop propagation.
   */
  onEvent: function(name, evt) {
    return true;
  },

  /**
   * transformResponse(text, xhr, elt)
   * Modify the raw response text before it is parsed and swapped into the DOM.
   * Use this to sanitize or preprocess HTML.
   */
  transformResponse: function(text, xhr, elt) {
    return text;
  },

  /**
   * isInlineSwap(swapStyle)
   * Return true if your extension will handle this swap style manually.
   * This tells HTMX to skip default behavior.
   */
  isInlineSwap: function(swapStyle) {
    return false;
  },

  /**
   * handleSwap(swapStyle, target, fragment, settleInfo)
   * Perform custom DOM manipulation if you implement a custom swap style.
   * Return true to prevent HTMX's default swap.
   */
  handleSwap: function(swapStyle, target, fragment, settleInfo) {
    return false;
  },

  /**
   * encodeParameters(xhr, parameters, elt)
   * Modify or serialize request parameters before sending.
   * Return null to use default URL/form encoding.
   * Return a string to override with a custom payload (e.g., JSON).
   */
  encodeParameters: function(xhr, parameters, elt) {
    return null;
  }
}

HTMX يوفر عدداً من الملحقات المسبقة الصنع التي يمكنك قراءة هنا.

على سبيل المثال، على سبيل المثال، مُدّمّاً مُدّمّاً json-encode يسمح بإرسال بيانات JJSON في جسم الطلب بدلاً من بيانات شكل URL- encoverd. هذا مفيد عندما تريد إرسال هياكل البيانات المركبة أو الصفائف إلى الخادم. يمكنك أن ترى أن هذا يصل إلى 3 أحداث

  • init - إنشاء امتداد وتخزين إشارة إلى مؤشر HTMX API
  • onEvent - وضع Content-Type مقدم إلى application/json « إذا ال المطلوب » أي ال أمر أمر أمر أمر الأمر في أمر أمر أمر أمر أمر أمر أمره و أمر أمر أمر أمره و أمر أمر أمره : أي : أي : إذا هذا ال أمر أمر أمر أمر أمر أمر أمر أمر أمر أمر أمر أمر أمر أمر أمر أمر أمر أمر أمر أمر أمر أمر أمر أمر أمر عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم هو هو هو هو خلق عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم هو هو هو هو هو خلق عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم هو هو هو هو هو خلق عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم هو هو هو هو هو عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم هو هو هو هو عظيم هو هو هو هو هو خلق عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم هو هو هو هو هو هو هو هو هو هو هو هو عظيم هو هو هو هو هو هو خلق عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم عظيم
  • encodeParameters - إلى تجاوز افتراضي URL- encodd from from font color = "red" (الترميز والتمديد) وتسلسل البارامترات كـ JSON. وهي أيضاً ترجع سلسلة نصية لمنع HTMX من استخدام الترميز الافتراضي لـ URL- encod from second.
(function() {
  let api
  htmx.defineExtension('json-enc', {
    init: function(apiRef) {
      api = apiRef
    },

    onEvent: function(name, evt) {
      if (name === 'htmx:configRequest') {
        evt.detail.headers['Content-Type'] = 'application/json'
      }
    },

    encodeParameters: function(xhr, parameters, elt) {
      xhr.overrideMimeType('text/json')

      const object = {}
      parameters.forEach(function(value, key) {
        if (Object.hasOwn(object, key)) {
          if (!Array.isArray(object[key])) {
            object[key] = [object[key]]
          }
          object[key].push(value)
        } else {
          object[key] = value
        }
      })

      const vals = api.getExpressionVars(elt)
      Object.keys(object).forEach(function(key) {
        // FormData encodes values as strings, restore hx-vals/hx-vars with their initial types
        object[key] = Object.hasOwn(vals, key) ? vals[key] : object[key]
      })

      return (JSON.stringify(object))
    }
  })
})()

او حتى الابسط ولكن اكثر hx-debug مضافاً إليها مضافاً HX-Debug ترويسة إلى طلب هذا هو مفيد لـ و الإيطالية الإيطالية إلى صورة خام طلب و ردّ البيانات بوصة dev كوميس.

(function() {
  htmx.defineExtension('debug', {
    onEvent: function(name, evt) {
      if (console.debug) {
        console.debug(name, evt)
      } else if (console) {
        console.log('DEBUG:', name, evt)
      } else {
        throw new Error('NO CONSOLE SUPPORTED')
      }
    }
  })
})()

هناك الكثير أكثر من ذلك بكثير، بما في ذلك قوة قوية جداً جانب العميل الجانبي يسمح لك باستخدام المكتبات التي تقوم بتأجير المكتبات في جانب العميل لتحويل بيانات Json المعادة إلى HTML. هذا مفيد لإنشاء URIs ديناميكية دون الحاجة إلى الاعتماد على تقديم جانب الخادم.

بعض الملاحق

على سبيل المثال في مشروع حديث استخدمت مبادلات HTMX OOB لتحديث عدد من الصفوف في الجدول. لفعل هذا اردت ان اعرف اي الصفات التي يتم عرضها حالياً في الجدول، لذا قمت فقط بتحديث الصفوف التي كانت مرئية.

رابعاً -

export default {
    encodeParameters: function (xhr, parameters, elt) {
        const ext = elt.getAttribute('hx-ext') || '';
        if (!ext.split(',').map(e => e.trim()).includes('dynamic-rowids')) {
            return null; // Use default behavior
        }

        const id = elt.dataset.id;
        const approve = elt.dataset.approve === 'true';
        const minimal = elt.dataset.minimal === 'true';
        const single = elt.dataset.single === 'true';

        const target = elt.dataset.target;
        const payload = { id, approve, minimal, single };

        if (approve && target) {
            const table = document.querySelector(target);
            if (table) {
                const rowIds = Array.from(table.querySelectorAll('tr[id^="row-"]'))
                    .map(row => row.id.replace('row-', ''));
                payload.rowIds = rowIds;
            }
        }

        // Merge payload into the parameters object
        Object.assign(parameters, payload);
        return null; // Return null to continue with default URL-encoded form encoding
    }
}

مستخدماً له

إلى استخدام الإيطالية نحن بحاجة إلى إضافة امتداد إلى HTMX تشكيلات. اذاً في ملف نقطة الدخول js (افترض انك تستخدم الوحدات؛ yoy يجب ان يكون) يمكنك ان تفعل شيئاً كهذا:

import dynamicRowIds from "./dynamicRowIds"; // Load the file

htmx.defineExtension("dynamic-rowids", dynamicRowIds); // Register the extension

ثم على أي عنصر من العناصر التي تريد استخدامها على يمكنك إضافة hx-ext dynamic-rowids.

                <button
                    hx-ext="dynamic-rowids"
                    data-target="#my-table"
                    data-id="@Model.Id"
                    data-param1="true"
                    data-param2="false"
                    data-param3="@Model.Whatever"
                    hx-post
                    hx-controller="Contoller"
                    hx-action="Action"
                >
                    <i class='bx bx-check text-xl text-white'></i>
                </button>

المزام

هذا هو ايضاً بسيطاً آخر HTMX امتداد، هذا الوقت مرتبط في htmx:configRequest كما نحن نقوم بتعديل الURL قبل إرسال الطلب. هذا الامتداد هو عامل إذا كنت تستخدم مرشّحة قائمة على الإقالة وإلى ذلك. وتريد بعض الطلبات للحفاظ على المرشّحات الموجودة بينما غير ذلك (على سبيل المثال، 'الاسم' و'البدء' ولكن ليس 'p' أو 'sort').

هذا مشابه لـ لكن ليس تماماً تماماً نفس مثل الحالي HTMx امتداد دفع المكافئات

رابعاً -

يمكنك أن ترى أن لدينا خط onEvent من أجل الإصغاء لـ htmx:configRequest حدث حدث.

ثم نحن:

  • احصل على العنصر الذي أطلق الحدث
  • (أ) الحصول على preserve-params-exclude من العنصر (إن كان موجوداً) و تقسيمه إلى مجموعة من المفاتيح لاستبعادها (إذاً نحن لا نضيفها إلى الطلب)
  • ا_ هذا العنوان الحالي من موقع النافذة
  • احصل على جديد الشيفر من الطلب UR UR
  • التنقيط من خلال البارامترات الحالية والتحقق إذا لم تكن مدرجة في قائمة الاستبعاد ولم تكن موجودة بالفعل في البارامترات الجديدة
  • وإذا لم تكن كذلك، نضيفها إلى البارامترات الجديدة
  • وأخيراً، نضع البارامترات الجديدة لعنوان الطلب ونعود بشكل حقيقي لمواصلة الطلب.
export default {
    onEvent: function (name, evt) {
        if (name !== 'htmx:configRequest') return;
        const el = evt.detail.elt;
        const excludeStr = el.getAttribute('preserve-params-exclude') || '';
        const exclude = excludeStr.split(',').map(s => s.trim());

        const currentParams = new URLSearchParams(window.location.search);
        const newParams = new URLSearchParams(evt.detail.path.split('?')[1] || '');

        currentParams.forEach((value, key) => {
            if (!exclude.includes(key) && !newParams.has(key)) {
                newParams.set(key, value);
            }
        });

        evt.detail.path = evt.detail.path.split('?')[0] + '?' + newParams.toString();

        return true;
    }
};

هنا أستعمل المادة الأساسية HTMX.Net من أجل علاماتها المساعدة. hx-controller وقد عقد مؤتمراً بشأن hx-action هي مساعِدات بطاقة التي تُولّد خواص HTMX الصحيحة لك. فضلاً عن ذلك hx-route-<x> لـ إلى تمرير بوصة المسار هذا هو هو إلى استخدام C رمز إلى توليد صحيح قيم لـ خصائص بدلا من إلى تشفير بوصة HTML.

مستخدماً له

أن تكون امتداداً من السهل حقاً إستخدامه:

أولاً نحن بحاجة إلى إضافة امتداد إلى تشكيل HTMX لدينا.


import preserveParams from './preserveParams.js';
htmx.defineExtension('preserve-params', preserveParams);

ملاحظة: ستلاحظ أن تمديدات HTMX الافتراضية تستخدم طريقة 'التحميل التلقائي' لتحميل التمديد.

// Autoloading the extension and registering it
(function() {
  htmx.defineExtension('debug', {
}

هذه طريقة جيدة للقيام بها إذا كنت تستخدم HTMx في بيئة غير متوحد غير متوحدية. على الرغم من ذلك، إذا كنت تستخدم الوحدات (التي يجب أن تكون عليها) فمن الأفضل أن تستخدم import لتحمّل التمديد ثمّ سجله بشكل صريح ضدّك htmx على سبيل المثال، هذا يتيح لك الاستفادة من ارتطام الأشجار فقط وتحميل الامتدادات التي تحتاج إليها.

ثم على عنصرك يمكنك إضافة hx-ext preserve-params وقد عقد مؤتمراً preserve-params-exclude مع a فاصلة قائمة من إلى استبعاد من طلب.


<a class="btn-outline-icon"
   hx-controller="MyController"
   hx-action="MyAction"
   hx-route-myparam="@MyParam"
   hx-push-url="true"
   hx-ext="preserve-params"
   preserve-params-exclude="page,sort"
   hx-target="#page-content"
   hx-swap="innerHTML show:top"
   hx-indicator>
    <i class="bx bx-search"></i>
</a>

في هذه القضية بسبب: event.detail.path لَهُ الجديدُ myparam قيمة وضعها في أنها سوف تستبدل هذا مع قيمة جديدة لدينا مع قيمة جديدة ولكن الحفاظ على جميع الآخرين (باستثناء page وقد عقد مؤتمراً بشأن sortحتى نتمكن من الاستمرار في تمرير أي مرشحات وضعناها في URL إلى الخادم دون أن نقلق من فقدانها عندما نقوم بطلب جديد.

المجموع الأساسي

أحد الأشياء المتقنة عن HTMX هو أن الكثير من تفاعله مع الخادم يحدث من خلال headers HTTP. هذه الترويسات تزود الخادم بسياق غني حول ما تسبب في الطلب، مما يسمح لك بالرد بشكل مناسب من نقاط نهاية ASP.NET الأساسية أو وجهات نظر المجازر.

والعنصر الأساسي في هذا هو: HTMX.Netمن بين العديد من البنود التي تقدمها تكون أنيقاً Request وهذا مفيد لتحديد ما إذا كان الطلب مقدماً من HTMX أم لا، ولمعالجة الطلب وفقاً لذلك.

كما أن لديها آليتها الخاصة لإرسال المنازعات


Response.Htmx(h => {
    h.WithTrigger("yes")
     .WithTrigger("cool", timing: HtmxTriggerTiming.AfterSettle)
     .WithTrigger("neat", new { valueForFrontEnd= 42, status= "Done!" }, timing: HtmxTriggerTiming.AfterSwap);
});

............................................................................................................................................................................................................... قام خالد بعمل عظيم في إنشاء مجموعة من التمديدات لجعل من السهل العمل مع HTMX في ASP.NET الأساسي.

إنها أداة رئيسية في صندوق أدواتي عندما أعمل مع HTMX و ASP.NET افحصه في الخارج!

مُروّم HTMX مُروّم

هنا توزيع للترويسات الأكثر فائدة التي يرسلها HTMX مع كل طلب:

/ ترويسة / وصف / |----------------------------|------------------------------------------------------------------------------------------------------------------| □ HX- o طلب ثابت دائماً ليكون صحيحاً لأي طلب مبدإ HTMX. عظيم للكشف عن مكالمات HTMX في البرمجيات المتوسطة أو أجهزة التحكم. □ هوية العنصر المستهدف في نظام DOM الذي سيتم مبادلة الرد به. □ HX-Triger □ هوية العنصر الذي دفع الطلب (مثل زر). □ □ □ □ HX-Triger-Name □ اسم عنصر الإدخال (مفيد للاستمارات). □ □ Two HX-Prompt □ مدخلات مستخدم من Hx- propstt. □ □ HX-Current-URL URL التصفح URL عند بدء الطلب. مفيد لقطع الأشجار والسياق. □ أُرسِلت الرسالة باعتبارها صحيحة إذا كان الطلب جزءا من عملية ترميم تاريخي بعد الملاحة (على سبيل المثال، زر ظهري).

أولاً - طلب التمديد

أنا أستخدم هذه بشكل مكثف في تطبيقاتي الأساسية ASP.net الأساسية. مجتمعة مع HTMX.Net Request.IsHtmx() , Request.IsHtmxBoosted() وقد عقد مؤتمراً بشأن Request.IsHtmxNonBoosted() يمكنك بسهولة الكشف عن طلبات HTMX والاستجابة وفقاً لذلك.

على سبيل المثال، لديّ تمديد بسيط جداً للطلب الذي يسمح لي بالكشف إذا كان الطلب يستهدف رئيسي #page-content إذا كان الأمر كذلك فأنا أعلم أنه يجب أن أعيد جزء منه ملاحظة: العديد لا يُدرك أنه يمكنك تحديد 'صفحة كاملة' على أنها جزئية، ثم تقوم فقط بالتخطّي عن المخطط.

        if (Request.PageContentTarget())
        {   
            Response.PushUrl(Request);
            return PartialView("List", vm);
        }
        return View("List", vm);
        
        public static class RequestExtensions
{
        
        public static bool PageContentTarget(this HttpRequest request)
    {
        bool isPageContentTarget = request.Headers.TryGetValue("hx-target", out var pageContentHeader) 
                                   && pageContentHeader == "page-content";
        
        return isPageContentTarget;
    }
    }

المُن المُنِدِد المُنِد المُن المُنِدِ المُنِكِ

بالإضافة إلى الطلبات الإضافية، يمكنك أيضاً إنشاء تمديدات استجابة لإرسال الأحداث إلى العميل. هذا مفيد لتحفيز الأحداث الجانبية للعميل.

مثال حلّ محل Alkrt

على سبيل المثال في تكاملي مع حليّتي الثانية أنا تمكين إغلاق حوار استخدام a زناد هو set من خادم.

    document.body.addEventListener('sweetalert:close', closeSweetAlertLoader);

هذا هو من خادم ك a HTMX مُطلَق.


    public static void CloseSweetAlert(this HttpResponse response)
    {
        response.Headers.Append("HX-Trigger" , JsonSerializer.Serialize(new
        {
            sweetalert = "close"
        }));

    }

هذا سَيُدّرر sweetalert:close حدث على جانب العميل، يسمح لك بإغلاق حوار الحوار. يمكنك أيضاً تمرر البيانات إلى العميل مستخدماً HX-Trigger الترويسة. هذا مفيد لنقل البيانات من الخادم إلى العميل دون الحاجة إلى تعديل رمز HTML أو جافاسكربت.

كما ترون، من السهل جداً الإستماع لهذه الأحداث بإضافة مستمع حدث إلى الجسم. أنا أستخدم (جيسون) بشكل رئيسي كما أنه دائماً يرمز بشكل صحيح.

لقد كتبت عن طريقتي المحمصة سابقاً هنا هناو لكن هذا يستحق الذكر هنا أيضاً. إلى تمكين الخادم من إطلاق رسالة نخبية على جانب العميل. لقد وضعت الزناد في هذا الامتداد الإستجابي.

    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
            }
        }));

    }

ثم أعلق في جانب عميل الحدث وأتصل بـ showToast الدالة الدالة.

import { showToast, showHTMXToast } from './toast';

window.showHTMXToast = showHTMXToast;

document.body.addEventListener("showToast", showHTMXToast);

ثمّ هذا يُدّعي إلى showToast و حسناً، تظهر نخباً، مرة أخرى ترى المزيد عنه في هذه المادة .



export function showHTMXToast(event) {
    const xhr = event?.detail?.xhr;
    let type = 'success';
    let message = xhr?.responseText || 'Done!';

    try {
        const data = xhr ? JSON.parse(xhr.responseText) : event.detail;

        if (data.toast) message = data.toast;
        if ('issuccess' in data) {
            type = data.issuccess === false ? 'error' : 'success';
        } else if (xhr?.status >= 400) {
            type = 'error';
        } else if (xhr?.status >= 300) {
            type = 'warning';
        }

    } catch {
        if (xhr?.status >= 400) type = 'error';
        else if (xhr?.status >= 300) type = 'warning';
    }

    showToast(message, 3000, type);
}

في الإستنتاج

حسنا هذا هو عليه، جولة صاعدة من HTMX و ASP.NET الأساسي. آمل أنكم وجدتم ذلك مفيدا ومفيدا. إذا كان لديكم أي أسئلة أو تعليقات، فتفضلوا بالتعليق أدناه.

مواد ذات صلة بشأن هذه القائمة

المادة المصاحبة

هذه المادة جزء من سلسلة من جزئين عن HTMX مع ASP.net fror:

  1. HTMX مع ASP.net - التركيز على التكامل الأساسي لشبكة APSP.net، والآراء الجزئية، وشبكة HTMX.net، والوصلة
  2. هذه المادة المادة - الغوص العميق في أحداث HTMX، ودورة الحياة، وبنية التمديد، والتمديدات الجمركية

مواد HTMX أكثر

& ما

الوثائق الرسمية HTMX الوثائق:

& الأدوات:

الموارد:

  • HTMx ديسرس - الدعم المجتمعي النشط
  • كتاب نُظم - كتاب مجاني على الإنترنت عن بناء تطبيقات فرط الضغط
Finding related posts...
logo

© 2026 Scott Galloway — Unlicense — All content and source code on this site is free to use, copy, modify, and sell.