كيفية إضافة محتويات يدوياً إلى pluginOutlet بعد استدعاء ajax؟ وكيفية إعادة عرض أو تحديث pluginOutlet؟

مرحباً، :wave:

أنا جديد على تصميم Discourse و emberjs، وأعمل حاليًا على سمة تحتوي على عناصر تنقل من الموقع الرئيسي.
يأتي ملف JSON لعناصر التنقل من طلب ajax وأحتاج إلى عرضه في مكانين.

المكان الأول هو header-buttons:before. تمكنت من القيام بذلك باستخدام api.decorateWidget وتشغيل site-header:force-refresh لـ appEvents.

ajax( settings.site_navigation_links_endpoint ).then((result) => {

	if (!result.length) {
		return;
	}

	result.map((customHeaderLinksArray) => {

		const anchorAttributes = {
			title  : customHeaderLinksArray.title,
			href   : customHeaderLinksArray.url,
			target : "self"
		};

		headerLinks.push(
			h(
				`li.custom-header-nav-item`,
				h( "a.custom-header-nav-item-link", anchorAttributes, customHeaderLinksArray.title )
			)
		);

	});

	headerNav = h("ul.custom-header-nav", headerLinks);

	if( settings.site_navigation_position == "inline" ) {
		api.decorateWidget("header-buttons:before", (helper) => {
			return headerNav;
		});
	}

	appEvents.trigger("site-header:force-refresh");

	// لعرضه في المكان (المكان الثاني، انظر أدناه)
	// ...
	// ...
}

المكان الثاني هو عبر pluginOutlet، below-site-header.
أعتقد أنه لا يمكنني فعل الشيء نفسه كما في الأعلى، باستخدام api.decorateWidget، لأن هذا pluginOutlet وليس widget (؟).

أسئلتي هي:

  1. كيف يمكنني إدراج محتوى ajax يدويًا في pluginOutlet؟
  2. أود أيضًا أن أعرف كيف يمكنني تجميع virtual-dom في الوقت المناسب بعد استدعاء ajax الخاص بي؟ على سبيل المثال، المتغير أعلاه، headerNav، أود الحصول على علامة HTML مجمعة له. لست متأكدًا من المكتبة / الدالة التي يجب استخدامها.
  3. إذا كان ذلك ممكنًا، كيف يمكنني أيضًا إعادة عرض pluginOutlet؟ مشابه لـ appEvents.trigger("site-header:force-refresh");

شكراً مقدمًا! :man_bowing:

إعجابَين (2)

صحيح. هناك طريقتان للقيام بذلك…

  1. يمكنك جعل التخصيص الخاص بك widget، ثم تحميل widget في plugin outlet هكذا:

    {{mount-widget widget="widget-name"}}
    

    يمكنك رؤية مثال لكيفية إنشاء widget في Discourse، على سبيل المثال شعار الصفحة الرئيسية: discourse/app/assets/javascripts/discourse/app/widgets/home-logo.js at 2dbcea9eeeb816dda347027497b3a49634ef851f · discourse/discourse · GitHub

    في سمة، ستضيف ملف widget-name.js الخاص بك إلى دليل javascripts/discourse/widgets

    هناك المزيد حول widgets في https://meta.discourse.org/t/a-tour-of-how-the-widget-virtual-dom-code-in-discourse-works/40347، ولكن لاحظ أننا سنتخلص تدريجياً من widgets، لذا فإن أي شيء تتعلمه في هذه العملية لن يكون مفيدًا على المدى الطويل.

  2. احتفظ بـ widget decorator الخاص بك كما هو، وأنشئ مكون Ember منفصلاً يقوم بما تريده في plugin outlet. لقد كنا نتخلص تدريجياً من widgets لصالح مكونات Ember (وهو ما بُني عليه معظم Discourse).

    ستبدو هذه العملية كالتالي:

    1. أنشئ ملف JS و HBS (قالب) للمكون في دليل javascripts/discourse/components الخاص بالسمة.
    • component-name.js

    • component-name.hbs

    1. قم ببناء مكون Ember الخاص بك… للأسف، هذه الخطوة هي في الأساس “تعلم Ember” (أدلة Ember) … ولكن أعتقد أن هذا قد يعطيك فكرة تقريبية للبدء:
    • في component-name.js:
    import Component from "@glimmer/component";
    import { tracked } from "@glimmer/tracking";
    import { action } from "@ember/object";
    
    const endpoint = settings.site_navigation_links_endpoint;
    
    export default class ComponentName extends Component {
      @tracked navLinks = null;
    
      @action
      async fetchNavLinks() {
       try {
          const response = await fetch(endpoint);
          const data = await response.json(); // نفترض أن هذا هو json
          this.navLinks = data;
        } catch (error) {
          console.error("فشل:", error);
        }
      }
    }
    
    • في component-name.hbs:
    <div {{did-insert this.fetchNavLinks}}>
     {{#each this.navLinks as |link|}}
       <a href={{link.anchor}}>{{link.title}}</a>
     {{/each}}
    </div>
    

    سيؤدي هذا إلى استدعاء الإجراء fetchNavLinks كلما تم إدراج المكون (في هذه الحالة، عند زيارة موقع Discourse وعرض التطبيق). كلما تم تحديث navLinks، سيتم تحديث محتوى المكون لأنه خاصية متعقبة.

    إذا كنت ترغب في تحديث الروابط بشكل متكرر أكثر من مجرد عرض المكون، فستحتاج إلى إضافة المزيد من المنطق إلى JS هنا… التحقق مما إذا كان المسار الحالي (الصفحة) يفي بشروط معينة على سبيل المثال.

    1. سيتم إضافة هذا المكون إلى plugin outlet عن طريق إضافته إلى الـ outlet في javascripts/discourse/connectors/below-site-header/my-component-connector.hbs:
    <ComponentName />
    
9 إعجابات

شكراً جزيلاً لك يا كريس! هذا مفيد جداً.

لقد اخترت النهج الثاني، باستخدام المكون (component)، حيث يتم التخلص تدريجياً من الأدوات (widgets). بصرف النظر عن الخطأ المطبعي الصغير في استدعاء الدالة، في ملف .hbs يجب أن يكون {{did-insert this. fetchNavLinks}}، كل شيء يعمل!

من الرائع معرفة أن لدينا did-insert، هذا يبعث على الارتياح! لقد انتهيت الآن من المهمة. :man_bowing:

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

آه، يسعدني أنك لاحظت ذلك، لقد قمت بتصحيح مشاركتي أعلاه

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

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