مع مرور الوقت، أصبح Discourse أكثر تعقيدًا، وقد يكون الأمر مرهقًا للمبتدئين لفهم كيفية انتقال البيانات بالكامل من تطبيق Ruby on Rails في الخلفية إلى تطبيق Ember.js في الواجهة الأمامية.
يهدف هذا الدليل إلى إظهار دورة الحياة الكاملة لطلب في Discourse وشرح الخطوات اللازمة إذا كنت ترغب في بناء صفحة جديدة بها عنوان URL خاص بها في تطبيقنا.
العناوين (URLs) أولاً
أفضّل دائمًا البدء بالتفكير في الميزات من خلال العناوين (URLs) للوصول إليها. على سبيل المثال، لنفترض أننا نريد بناء ميزة إدارية تعرض آخر وجبة خفيفة تناولتها أثناء العمل على Discourse. عنوان مناسب لذلك سيكون /admin/snack
في هذه الحالة:
-
زيارة
/admin/snackفي متصفحك يجب أن تعرض الوجبة الخفيفة باستخدام “المنصة الكاملة” (full stack)، بمعنى آخر، سيتم تحميل تطبيق Ember وسيطلب البيانات التي يحتاجها لعرض الوجبة. -
زيارة
/admin/snack.jsonيجب أن تعيد بيانات JSON الخاصة بالوجبة نفسها.
جانب الخادم (Ruby on Rails)
لنبدأ بإنشاء متحكم (controller) جديد للوجبة الخفيفة.
app/controllers/admin/snack_controller.rb
class Admin::SnackController < Admin::AdminController
def index
render json: { name: "donut", description: "delicious!" }
end
end
في هذه الحالة، نرث من Admin::AdminController للحصول على جميع فحوصات الأمان للتأكد من أن المستخدم الذي يعرض المتحكم هو مدير. لدينا شيء واحد آخر يجب القيام به قبل أن نتمكن من الوصول إلى متحكمنا، وهو إضافة سطر إلى config/routes.rb:
ابحث عن الكتلة التي تبدو هكذا:
namespace :admin, constraints: StaffConstraint.new do
# lots of stuff
end
وأضف هذا السطر بداخلها:
get 'snack' => 'snack#index'
بمجرد الانتهاء، يجب أن تكون قادرًا على زيارة /admin/snack.json في متصفحك وسترى بيانات JSON للوجبة الخفيفة! يبدو أن واجهة برمجة تطبيقات الوجبات الخفيفة (snack API) لدينا تعمل ![]()
بالطبع، أثناء بناء ميزتك وإضافة المزيد من التعقيد، على الأرجح لن تعيد ببساطة JSON مُثبّتة (hardcoded) من متحكم كهذا، بل ستستعلم عن قاعدة البيانات وتعيد النتائج بهذه الطريقة.
جانب العميل (Ember.js)
إذا فتحت متصفحك وزيارة /admin/snack (بدون .json)، فسترى أن Discourse يقول “عذرًا! هذه الصفحة غير موجودة.” — وذلك لأنه لا يوجد شيء في تطبيقنا الأمامي Ember للرد على المسار (route). لنقم بإضافة قالب .gjs لعرض وجبتنا الخفيفة:
app/assets/javascripts/admin/templates/snack.gjs
<template>
<h1>{{@controller.model.name}}</h1>
<hr />
<p>{{@controller.model.description}}</p>
</template>
و، كما في جانب واجهة برمجة تطبيقات Rails، نحتاج إلى ربط المسار. افتح الملف app/assets/javascripts/admin/routes/admin-route-map.js وابحث عن الدالة export default function(). أضف السطر التالي:
this.route("snack");
لدينا شيء أخير يجب القيام به في عالم Ember، وهو جعل تطبيق Ember يقوم بطلب AJAX لجلب JSON الخاص بنا من الخادم. لننشئ ملفًا أخيرًا. سيكون هذا مسار Ember (Ember Route). ستتم استدعاء دالة model() الخاصة به عند دخول المسار، لذا سنقوم بعملية ajax هناك:
app/assets/javascripts/admin/routes/admin-snack.js
import { ajax } from "discourse/lib/ajax";
export default Ember.Route.extend({
model() {
return ajax("/admin/snack.json");
},
});
الآن، يمكنك فتح متصفحك على /admin/snack وسترى تفاصيل الوجبة الخفيفة معروضة في الصفحة!
ملخص
-
فتح متصفحك على
/admin/snackيشغّل تطبيق Ember -
يقول موجّه تطبيق Ember (router) أن
snackيجب أن يكون هو المسار -
يقوم مسار Ember الخاص بـ
snackبطلب AJAX إلى/admin/snack.json -
يقول موجّه تطبيق Rails أن هذا يجب أن يكون
admin_snack controller -
يعيد
admin_snack_controllerبيانات JSON -
يحصل تطبيق Ember على بيانات JSON ويعرض قالب
.gjs
إلى أين من هنا
لقد كتبتُ دليل متابعة حول كيفية إضافة مكوّن Ember (Ember Component) إلى Discourse.
هذا المستند مُدار بإصداراته (version controlled) - اقترح التغييرات على github.