ودية الفضاء المفتوح JS: التقديم من جانب العميل وإنشاء التفاف

تعتبر Open Friendly Space إطارًا شابًا للغاية ، لكنها تعرف بالفعل كيفية تشغيل :-)


في هذه المقالة حول تطوير "Friendly Open Space" ، سنتقن تقديم القالب في المتصفح ونطلق التطبيق على قاعدة بيانات الملفات المحلية.

يدعم إطار العمل نوعين من تجميع القوالب على العميل:

  1. تقديم جانب العميل بالكامل
  2. تم تقديم طلب لتقديم القالب إلى الخادم ، يليه إخراجه في نافذة المتصفح.

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

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

إعداد التطبيق وإعداده


وبالتالي ، فإننا نواجه مهمة إنشاء تطبيق من صفحة واحدة يؤدي إلى تقديم نموذجين (windows) من جانب العميل. في ضوء مهمة بسيطة إلى حد ما ، سنفعل بدون قاعدة بيانات MySQL وتوقعاتها ، لذلك سنقوم بتوجيه جميع أعمال FSQL إلى ملف ، أي سنستخدم قاعدة البيانات الموجودة على الملف للعمل مع الآليات الداخلية للإطار. حسنًا ، لنبدأ.

إنشاء الدلائل:

القوالب - دليل القوالب
المغلق - دليل ملفات المغلق
fos - قم بتنزيل أحدث إصدار بيتا friendlyopenspace.site/en/download
ضع favicon.ico مزعج في الدليل الجذر للتطبيق: favicon.ico

وأيضًا ، نضع على الفور ملفات الأنماط في دليل css: window.css و styles.css

بعد ذلك ، قم بإنشاء ملف التطبيق application.js نفسه:

var fos = require("./fos/fos"); fos.module({ name: "application.js", dependencies: [ "fos:NServer/Application.js", ], module: function(application) { application.setSettings({ port: 3001, packages: [], dynamicLoading: true, clientRenderingMode: "client", dataClient: { defaultConnection: "default", connections: { default: { type: "file", file: "data.fosdb" } }, }, onInitialize: function(a_event) { if (!a_event.error) { application.run(); } else { console.error(a_event.error); } } }); application.getRouter().add([ { route: "", controller: "fos:NServer/NControllers/Tmpl.js", source: "templates/page.tmpl", }, { route: "/css/*", controller: "fos:NServer/NControllers/File.js", source: "css", }, { route: "/templates/*", controller: "fos:NServer/NControllers/File.js", source: "templates", }, { route: "favicon.ico", controller: "fos:NServer/NControllers/File.js", source: "favicon.ico", }, ]); application.initialize(); } }); 

الآن دعونا نلقي نظرة على محتويات ملف application.js

قمنا بتعطيل جميع الحزم ، حيث لم تكن هناك حاجة إليها (معلمة الحزم الخاصة بأسلوب setSettings):

  ... application.setSettings({ port: 3001, packages: [], dynamicLoading: true, clientRenderingMode: "client", ... 

معلمة التطبيق clientRenderingMode ، الجديدة بالنسبة لنا ، مسؤولة عن نوع التجسيد على العميل ولديها قيمتان:

"العميل" - يتم التقديم بالكامل بواسطة المتصفح. يقوم العميل بشكل مستقل بتحميل التبعيات وتنفيذ استعلامات FSQL إلى الخادم ، وبعد ذلك يقوم بتجميع HTML نفسه

"الخادم" - يقدم العميل طلبًا إلى الخادم لتقديم القالب ويتلقى HTML جاهزًا كرد

  ... packages: [], dynamicLoading: true, clientRenderingMode: "client", dataClient: { defaultConnection: "default", ... 

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

 ... defaultConnection: "default", connections: { default: { type: "file", file: "data.fosdb" } }, }, ... 

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

إنشاء قالب الصفحة


حان الوقت الآن لإنشاء قوالب / page.tmpl ملف قالب صفحة التطبيق ، والتي سجلناها في مسار URL الجذر.

 //~OPTIONS { args:{ fosInclude: ["css/styles.css"], } } //~BLOCK main default <!DOCTYPE html> <html> <head> <meta charset="utf-8"/> %{{ render.renderHTMLHeader(); }}% <script> function onClientSideRendering(a_event){ a_event.preventDefault(); fos.application.render({ template: "templates/window.tmpl", owner: document.body, args: { title: "Client side rendering", context: "Simple example of client side rendering" }, onResult: function(a_error, a_template){ } }); } function onServerSideRendering(a_event){ a_event.preventDefault(); fos.application.render({ template: "templates/window.tmpl", owner: document.body, renderMode: "server", args: { title: "Server side rendering", context: "Simple example of server side rendering" }, onResult: function(a_error, a_template){ } }); } </script> </head> <body> <div class="mainwrapper"> <div class="header markup"> Client Side Rendering </div> <div class="body-wrapper markup"> <div class="body markup"> <p class="example-link--container"><a onclick="onClientSideRendering(event);">Client side rendering</a></p> <p class="example-link--container"><a onclick="onServerSideRendering(event);">Server side rendering</a></p> </div> <div class="clear-body"></div> </div> </div> </body> </html> 

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

عندما نقر على رابط "عرض جانب العميل" ، فإننا ندعو وظيفة onClientSideRendering () ، والتي تعرض قالب "القوالب / window.tmpl". تماما على جانب العميل ، كما في إعدادات التطبيق ، تم تعيين المعلمة clientRenderingMode إلى "العميل". على الرغم من حقيقة أن هذه هي القيمة الافتراضية :-).

 function onClientSideRendering(a_event){ a_event.preventDefault(); fos.application.render({ template: "templates/window.tmpl", owner: document.body, args: { title: "Client side rendering", context: "Simple example of client side rendering" }, onResult: function(a_error, a_template){ } }); } 

تعرض طريقة التجسيد فعليًا نافذتنا وتضعها في نص الصفحة ، كما هو محدد في خاصية وسيطة المالك. نقوم بتمرير وسيطين اثنين إلى قالب النافذة: العنوان والسياق ، في الواقع ما سيتم عرضه في النافذة المعروضة. لمزيد من المعلومات حول الطريقة ، راجع fos :: NClient :: Application :: render

يستدعي الارتباط الثاني وظيفة onServerSideRendering () ، التي تعرض القالب نفسه بالمثل ، ولكن من جانب الخادم ، ويتلقى العميل HTML جاهز. يتم تعيين هذا الوضع في خاصية وسيطة renderMode الخاصة بأسلوب التقديم باستخدام القيمة "server".

 function onServerSideRendering(a_event){ a_event.preventDefault(); fos.application.render({ template: "templates/window.tmpl", owner: document.body, renderMode: "server", args: { title: "Server side rendering", context: "Simple example of server side rendering" }, onResult: function(a_error, a_template){ } }); } 

إنشاء قالب منبثق وكتابة قالب مجمّع


قالب نافذة منبثقة في حد ذاته بسيط جدا. قم بإنشاء ملف القوالب / window.tmpl. وفيما يلي محتوياته.

 //~OPTIONS { args:{ fosWrapper: true, fosClass: "window", fosInclude: ["css/window.css"], title: "", context: "", } } //~BLOCK main default <div class="window-container"> <div class="window-close" name="close">x</div> <div class="window-title">${{args.title}}$</div> <div class="window-context">${{args.context}}$</div> </div> 

هنا بالنسبة لك هناك معلمتان جديدتان fosWrapper و fosClass.

لنبدأ مع fosWrapper. إذا تم تعيين هذه العلامة على "صحيح" ، فسيتم وضع قالب HTML في الحاوية span ويتم إنشاء كائن مجمّع fos :: NRender :: Wrapper من أجله.

قم بتشغيل التطبيق ، انتقل إلى المضيف المحلي: 3001 وانقر على الرابط "تقديم جانب العميل". النافذة المنبثقة هي قالبنا. يتم تطبيق نافذة منبثقة بالكامل بواسطة css (ملف css / window.css) - ذكرت للتو أنك لن تبحث عن JS :-) المخفي.

افتح متصفح DevTools (Ctrl + Alt + i) ، انتقل إلى علامة تبويب "العناصر" وراجع هيكل نافذتنا.

صورة

يشير الخط الأزرق في الشكل إلى حاوية التفاف الامتداد التي يتصل بها كائن fos :: NRender :: Wrapper.

وسيطة النظام التالية إلى القالب هي fosClass. إنه ببساطة يضيف فئة CSS إلى حاوية امتداد المجمع.

وهكذا ، كان كل شيء جيدًا ، لكن إذا حاولنا إغلاق النوافذ المنبثقة ، فلن يتحقق شيء. نعم ، لم نكتب عملية إغلاق بعد!

كما قلنا سابقًا ، إذا كانت وسيطة النظام fosWrapper صحيحة ، فسيتم إنشاء كائن المجمع fos :: NRender :: Wrapper للقالب. يوفر واجهة قياسية للتفاعل مع القالب على العميل. لإعادة تعريف المجمع القياسي لقالب ، يكفي إنشاء وحدة نمطية بالاسم المطابق للتنسيق التالي [PATTERN NAME] .wrapper.js ، ويجب أن توارث الوحدة النمطية من الفئة fos :: NRender :: Wrapper.

الآن إنشاء ملف مجمّع للقالب / window.tmpl القالب. سيتعين على الفئة الجديدة إغلاق النافذة المنبثقة ، عند النقر فوق الرمز "x".

قوالب الملفات / window.wrapper.js:

 fos.module({ name: "templates/window.wrapper.js", dependencies: ["fos:NRender/Wrapper.js"], module: function(Wrapper){ return function(a_initializeOptions) { var self = this; Wrapper.call(this, a_initializeOptions); var parentAttach = this._attach; this._attach = function(a_cb) { parentAttach.call(this, function(){ fos.addDomListener(fos.select(self.getDomElement(), "[name=close]")[0], "click", function(){ self.getDomElement().classList.add("window-hide"); setTimeout(function() { self.destroy(); }, 2000); }); a_cb(); }); } } } }); 

دعنا نحلل محتويات وحدتنا. أولاً ، نقوم بتوصيل الفئة الأساسية fos :: NRender :: Wrapper ونرثها من خلال طريقة الاتصال.

 fos.module({ name: "templates/window.wrapper.js", dependencies: ["fos:NRender/Wrapper.js"], module: function(Wrapper){ return function(a_initializeOptions) { var self = this; Wrapper.call(this, a_initializeOptions); ... 

بعد أن نقوم بإعادة تعريف طريقة fos :: NRender :: Wrapper :: _ إرفاق ، والتي تسمى عندما يرتبط القالب بالكائن. في هذه الطريقة ، سوف نقوم بتوصيل حدث النقر على الرابط لإغلاق النافذة. تتم عملية التجاوز ببساطة عن طريق إعلان الطريقة ، ولكن في البداية يجب أن نحتفظ بالإشارة إلى التطبيق الأصل. الأسلوب له "طبيعة غير متزامنة" ، لذلك نضع تنفيذ إجراءاتنا في وظيفة رد الاتصال للتنفيذ الأصل.

  ... var parentAttach = this._attach; this._attach = function(a_cb) { parentAttach.call(this, function(){ fos.addDomListener(fos.select(self.getDomElement(), "[name=close]")[0], "click", function(){ self.getDomElement().classList.add("window-hide"); setTimeout(function() { self.destroy(); }, 2000); }); a_cb(); }); } ... 

عند الاتصال بحدث النقر فوق الرمز "x" ، فإننا ننفذ عن طريق الاتصال بـ fos :: addDomListener ، والذي لا يعيد تعيين الأحداث المتصلة عند تغيير أصل عنصر DOM.

في معالج الأحداث ، نغلق النافذة. أولاً ، قمنا بإزالة النافذة بشكل جيد من الشاشة بإضافة فئة CSS "إخفاء النوافذ". بعد اكتمال الرسوم المتحركة ، نسميها طريقة fos :: NRender :: Wrapper :: إتلاف ، التي تزيل القالب وكائن المجمع.

جميع التطبيقات مكتوبة ، أطلقت وعاودت!

 node application.js 

موقع التطوير الرسمي

رابط إلى مثال

Source: https://habr.com/ru/post/ar473154/


All Articles