إعادة فتح Widget باستدعاء AJAX

هذا موضوع تم طرحه عدة مرات وتوقف (عادةً لأن المطور لا يتطلب فعليًا استدعاء AJAX). ومع ذلك، أقوم بتطوير إضافة تصل إلى بيانات غير مخزنة في قاعدة بيانات Discourse (بوت Discord مستقل بذاته) وأحاول استخدام تلك البيانات لتزيين المشاركات.

export default Component.extend({
  init() {
    this._super(...arguments);

    var self = this;
    const store = getOwner(this).lookup("service:store");

      let positions = [];

    store
      .findAll("position", {
        ...args,
      })
      .then((data) => {

        for (const [key, position] of Object.entries(data.content)) {
          positions.pushObject(EmberObject.create({ ...position }));
        }
      });

    withPluginApi("1.4.0", (api) => {
      api.reopenWidget("post", {
        html(attrs) {
          let position = positions.filter(
            (position) => position.user.id == attrs.user.id
          );

          if (position.length > 0) {
            attrs.cooked = "Has Position";
          }

          return this.attach("post-article", attrs);
        },
      });
    });
  },
});

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

تمت كل هذه المحاولات في وقت متأخر من الليل، لذا من المحتمل جدًا أنني أغفل شيئًا واضحًا جدًا، ومع ذلك، سيكون أي مساعدة موضع تقدير كبير.

يعتمد على ما تحاول القيام به على ما أعتقد، ولكن لماذا لا تستخدم واجهة برمجة تطبيقات Discord Ruby الرسمية للحصول على البيانات في قاعدة بيانات Discourse، وتسلسلها إلى العميل، ثم استخدامها في الأداة؟

بدا الأمر تعقيدًا غير ضروري عندما تكون واجهة برمجة التطبيقات (API) للتطبيقات الأساسية جيدة بما يكفي لمعظم الأشياء، ولكن قد أسيء فهم التنفيذ حيث سأحتاج بصراحة إلى دراسة جانب Ruby من discourse بشكل أكبر.

على الرغم من أنه إذا لم أتمكن من جعل تزيين المنشورات يعمل، فمن المحتمل أن أضطر إلى اتباع هذا المسار.

بالعودة لتقديم الشكر لـ @merefield، تعمقت أكثر في التسلسل وتمكنت من إنجاز المهمة عن طريق إجراء استدعاء API في المُسلسل بدلاً من طلبه من JS كما كنت أفعل.

أنا متأكد من وجود عدد لا يحصى من الأسباب لعدم اقتراح هذا، ولكنه يعمل بالنسبة لي لذا سأستمر في استخدامه، ولمن يجد هذا في المستقبل، يمكنك إدخال البيانات في مُسلسل باستخدام الكود التالي:

add_to_serializer(:topic_view, :data_name) do
    JSON.parse(Net::HTTP.get(URI('https://yourwebsite.com?topic_id=' + object.topic.id.to_s)))
end

مما يسمح لك بعد ذلك بالوصول إلى البيانات ضمن استدعاء لـ reopenWidget. في حالتي، أضيف البيانات المتعلقة بالموضوع إلى مُسلسل topic_view والوصول إليها أثناء تعديل المنشور على النحو التالي:

api.reopenWidget("post", {
          html(attrs) {
            let data_name = this.model.topic.data_name;

            // قم بعمل أشياء بالبيانات

            return this.attach("post-article", attrs);
          },
        });

كما ذكرت سابقًا، هناك على الأرجح الكثير من الأسباب لعدم كون هذه هي الطريقة الصحيحة للقيام بذلك، ولكنه يعمل لحالتي بأقل تأثير على أوقات التحميل.

لمن يسعون لإنجاز المهمة داخل JS لأي سبب كان، يبدو أن الكود ذي الصلة موجود في إضافة discourse-encrypt حيث يقومون بفك تشفير المنشورات، ولكني وجدت هذه الطريقة أسهل بكثير في التنفيذ: discourse-encrypt/assets/javascripts/discourse/initializers/decrypt-posts.js at 255724ebc5fc3956f26beca09c1f7cb273d76eb2 · discourse/discourse-encrypt · GitHub

يبدو أن هذا يكسر مكون السمة “Topic Thumbnails” بشكل غريب عن طريق جعل الصور كبيرة جدًا GitHub - discourse/discourse-topic-thumbnails: Display thumbnails in topic lists

تفاعل غريب حقًا، لا شيء آخر ملحوظ مع ذلك.

هممم… لست متأكدًا من أن هذا سليم من الناحية المعمارية. بينما من الرائع أنك تستكشف حلاً من جانب الخادم (يجب أن تحدث استدعاءات الخادم عن بُعد دائمًا تقريبًا بين العمليات على جانب الخادم، خاصة عندما يتعلق الأمر بالمصادقة والترخيص)، يجب تحميل البيانات بشكل غير متزامن، ولا يجب أن يعتمد المُسلسل على مكالمة عن بُعد للانتهاء للاستنتاج. على الأقل، يجب عليك تغليف تلك المكالمة في ذاكرة تخزين مؤقت؟

انظر كيف تسير الأمور، ولكن انتبه جيدًا لتوقيت تحميل الصفحة قبل وبعد هذا التغيير، فقد تكون تُدخل تأخيرًا كبيرًا.

في الواقع، يضيف ما بين 10-50 مللي ثانية لكل تحميل إن وجد. الاتصال ذو زمن انتقال منخفض للغاية حيث أن كلا الصندوقين موجودان في نفس مركز البيانات. في الواقع، الطريقة التي أستخدمها لجلب البيانات إلى المكونات تقوم بتحميل الصفحات بشكل أسرع بشكل هامشي من عرض ديسكورس لصفحاته الثابتة (فرق حوالي 100 مللي ثانية) وهذا يشمل عملية قاعدة بيانات تستخدم معرفات Discord لإضافة بيانات المستخدم إلى استجابات API قبل إرسالها إلى العميل. (يطلب Ruby البيانات من التطبيق الخارجي → تحليل JSON → حلقة each لاستعلام قاعدة البيانات لإلحاق البيانات بالاستجابة → إنشاء JSON وإعادته إلى عميل الواجهة الأمامية). هذا مفهوم بالنظر إلى حجم قاعدة التعليمات البرمجية، ولكن هناك بالتأكيد عبء داخلي يفسح المجال لهذه الطلبات التي تُعتبر تقليديًا “مكلفة” لتمر دون أن يلاحظها أحد تمامًا. ومع ذلك، نحن نتحدث عن سرعة الضوء والصوت هنا، والتي لا تزال سريعة بشكل لا يصدق للمستخدم النهائي لأن ديسكورس منصة رائعة.

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

أقدر جدًا هذه الرؤية، وأنا بالتأكيد متحمس لمواصلة تعلم المزيد عن هذه المنصة والمساهمة فيها في المستقبل.

3 إعجابات

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.