كيفية حقن خدمة في الخطاب؟

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

كيف يمكنني تسجيل خدمة بشكل صحيح في Discourse؟ لقد اتبعت الموضوع هنا، وكود المكون الإضافي ذي الصلة على github، ولكنني غير قادر على جعله يعمل.

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


إليك بعض الأكواد التي جربتها:

javascripts/discourse/services/great-stuff.js:

import Service, { inject as service } from "@ember/service";

export default class GreatStuffService extends Service {
    call() {
        console.log('you called it')
    }
}

connectors/topic-list-after-title/sample-outlet.js.es6:

import { inject as service } from "@ember/service";

export default {
  greatStuff: service(),
  actions: {
      buttonPressInOutlet(){
         this.greatStuff.call()
     }
  }
}

عندما أقوم باستدعاء الإجراء “buttonPressInOutlet()” أحصل على الخطأ: Uncaught TypeError: Cannot read properties of undefined (reading 'call').

ما هو المطلوب أيضًا؟

قد ترغب في إلقاء نظرة على كيفية كتابة الخدمات الأخرى. لا أعتقد أن صيغة x extends y تعمل بعد على إصدار Ember الذي يستخدمه Discourse.

قد ترغب أيضًا في إلقاء نظرة على واجهة برمجة تطبيقات appEvents للتواصل بين مكونين.

إعجابَين (2)

المشكلة هنا هي أن ‘connector’ ليس EmberObject، وبالتالي لا يمكنك حقن الأشياء فيه. بدلاً من ذلك، ستحتاج إلى إنشاء مكون Ember وحقنه هناك.

سيبدو قالب ‘connector’ الخاص بك بعد ذلك شيئًا مثل

{{my-component-name}}

إليك مثال على كيفية القيام بذلك في المكون الإضافي whos-online:

لدينا خدمة في النواة:

قالب موصل في المكون الإضافي

تعريف المكون:
https://github.com/discourse/discourse-whos-online/blob/main/assets/javascripts/discourse/components/whos-online.js#L6-L7

(أو يمكنك استخدام export default Component.extend({ whosOnline: service() }) إذا كنت تفضل ذلك)

وقالب المكون:
https://github.com/discourse/discourse-whos-online/blob/main/assets/javascripts/discourse/templates/components/whos-online.hbs

3 إعجابات

لم أفكر في ذلك. شكراً على الفكرة!


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

الآن أحاول فرز النصف الآخر - بمجرد استدعاء إجراء في خدمة، اجعلها تشغل إجراءً في مكون. أعتقد أنها تشبه استيراد المكون في الخدمة واستدعاء دالة في هذا المكون (و/أو الاشتراك في الإجراء في المكون). لكنني لم أحصل على الصيغة بعد.

بافتراض أن هذا صحيح، هل لديك أي أمثلة للصيغة؟

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

ومع ذلك، قد يكون من الضروري أحيانًا إنجاز شيء ما ضمن قيود نظام منافذ الإضافات في Discourse.

أوصي بنفس ما أوصى به @fzngagan - ألقِ نظرة على appEvents. إنها ربما الطريقة الأنظف لتشغيل منطق المكون من خدمة.

إعجابَين (2)

اعتقدت أن هذا هو ما كان evented مخصصًا له، لكنني لم أستخدمه من قبل. الهدف هو فقط الحصول على إعداد شبيه بـ ipc حيث

  • ينقر المستخدم على زر في المكون أ
  • يتسبب هذا النقر في تحميل البيانات في المكون ب

أنا أكثر دراية بـ Angular، حيث يكون إنشاء خدمة والاشتراك فيها هو الطريقة العامة للقيام بذلك. ولكن في Discourse، هل أفضل طريقة هي appEvents؟

بالضبط! appEvents هو غلاف لـ Evented. إذا كنت تفضل استخدام Evented مباشرة، فهذا جيد أيضًا :+1:

https://github.com/discourse/discourse/blob/main/app/assets/javascripts/discourse/app/services/app-events.js#L4

إعجاب واحد (1)

:slight_smile: مثير للاهتمام! شكرًا على المتابعة. لستُ معتادًا على evented - لم أستخدمه من قبل وكنت أواجه بعض الصعوبة في بناء الجملة في خدمة Discourse:
export default class GreatStuffService extends Service.extends(Evented, {...})
ليس صحيحًا تمامًا.

لم أستخدم appEvents من قبل أيضًا. هل يمكنني إنشاء appEvent جديد في مكون إضافي/سمة يمكنني الاشتراك فيه بعد ذلك؟ معظم الأمثلة التي أجدها تتعلق بالاشتراك في appEvents المعدة بالفعل في نواة Discourse.

إعجاب واحد (1)

نعم يمكنك فعل ذلك. ابحث عن appEvents.trigger

إعجابَين (2)