أهم 8 أخطاء شائعة يرتكبها مطورو Backbone.js
نشرت: 2022-03-11Backbone.js هو إطار عمل مبسط يهدف إلى توفير مجموعة بسيطة من هياكل البيانات والميزات التي يمكنك استخدامها لإنشاء واجهة أمامية لتطبيق ويب منظم. من خارج الصندوق ، توفر مكونات Backbone.js بيئة سهلة الاستخدام قد تكون على دراية بها بالفعل عند العمل مع النماذج وطرق العرض على النهاية الخلفية. تعتبر النماذج والمجموعات في Backbone.js بسيطة ، ولكنها تأتي مع بعض الميزات المفيدة جدًا ، مثل خيار دمجها بسهولة مع واجهات برمجة تطبيقات REST JSON. لكنها أيضًا مرنة بما يكفي لتتكيف مع أي استخدام عملي تقريبًا.
في هذا البرنامج التعليمي Backbone.js ، سنلقي نظرة على بعض الأخطاء الشائعة التي غالبًا ما يرتكبها المطورون المستقلون ويأخذون أولى خطواتهم في تعلم Backbone.js وطرق تجنبها.
الخطأ الأول: تجاهل ترسانة وظائف Backbone.js
قد يكون Backbone.js إطارًا مبسطًا ، ولكنه (جنبًا إلى جنب مع Underscore.js) يوفر عددًا كبيرًا من الميزات والوظائف التي يمكن أن تغطي بسهولة أبسط الاحتياجات الأساسية وبعض الاحتياجات الضرورية التي تنشأ عند تطوير تطبيق ويب حديث. أحد الأخطاء الشائعة التي يرتكبها المطورون المبتدئون غالبًا هو أنهم يتخذون Backbone.js ليكون إطار عمل عميل آخر يشبه MVC للويب. على الرغم من أن هذا القسم يتحدث عن شيء واضح جدًا ، عندما يتعلق الأمر بـ Backbone.js فمن الخطأ الفادح حقًا عدم استكشاف إطار العمل تمامًا. قد يكون إطار العمل صغير الحجم ، ولكن هذا ما يجعله مرشحًا رائعًا لهذا الاستكشاف الشامل. خاصة كود المصدر صغير الحجم ومشروح بشكل جيد.
يوفر Backbone.js الحد الأدنى المطلوب لمنح تطبيق الويب الخاص بك الهيكل الذي يمكنه الاستفادة منه. بفضل قابليته للتوسعة وعدد كبير من المكونات الإضافية ، يمكن استخدام تعلم Backbone.js لبناء بعض تطبيقات الويب الرائعة. يتم عرض بعض أكثر ميزات Backbone.js وضوحًا من خلال النماذج والمجموعات والمشاهد. توفر مكونات جهاز التوجيه والمحفوظات آلية بسيطة لكنها أنيقة لدعم التوجيه من جانب العميل. على الرغم من أن Underscore.js هي تبعية لـ Backbone.js ، إلا أنها مدمجة جيدًا في إطار العمل ، حيث تستفيد النماذج والمجموعات كثيرًا من حزام الأداة المذهل هذا لجافا سكريبت ومتاح أيضًا تحت تصرفك.
تمت كتابة الكود المصدري لإطار العمل بشكل جيد وشروحه بحيث يمكن للمرء على الأرجح قراءته بالكامل أثناء شرب فنجان من القهوة. يمكن للمبتدئين الاستفادة كثيرًا من قراءة التعليقات التوضيحية المصدر ، حيث يمكنهم معرفة الكثير حول كيفية عمل إطار العمل داخليًا ، وكذلك تبني مجموعة رائعة من أفضل الممارسات عندما يتعلق الأمر بجافا سكريبت.
الخطأ الثاني: تعديل DOM في الاستجابة المباشرة للأحداث التعسفية
الشيء الذي نميل إلى القيام به عندما نبدأ في تعلم Backbone.js هو عدم القيام بالأشياء على النحو الموصى به من قبل Backbone.js. على سبيل المثال ، نميل إلى التعامل مع الأحداث وعرض التحديثات بالطريقة التي نتبعها مع jQuery على مواقع الويب البسيطة. يهدف Backbone.js إلى منح تطبيق الويب الخاص بك بنية صلبة من خلال الفصل المناسب بين الاهتمامات. غالبًا ما نميل إلى القيام به مع Backbone.js هو تحديث طريقة عرض ردًا على أحداث DOM التعسفية:
var AudioPlayerControls = Backbone.View.extend({ events: { 'click .btn-play, .btn-pause': function(event) { $(event.target).toggleClass('btn-play btn-pause') } }, // ... })هذا شيء يجب تجنبه بأي ثمن. قد يكون من الممكن الخروج بأمثلة غامضة حيث يكون ذلك منطقيًا ؛ ولكن في معظم الحالات ، هناك طرق أفضل بكثير للقيام بذلك. في الواقع ، إحدى الطرق التي يمكنني تمثيلها هنا هي استخدام النموذج لتتبع حالة مشغل الصوت واستخدام معلومات الحالة هذه لعرض الزر (أو بشكل أكثر تحديدًا أسماء فئته):
var AudioPlayerControls = Backbone.View.extend({ events: { 'click .btn-play, .btn-pause': function(event) { this.model.set('playing', !this.model.get('playing')) } }, initialize: function() { this.listenTo(this.model, 'change', this.render) this.render() }, // ... }) <button class=”btn btn-<%- playing ? 'pause' : 'play' %>”></button>قد تكون هناك حالات نادرة يكون فيها التلاعب المباشر بـ DOM من معالجات الأحداث منطقيًا ، ولكن التكلفة التي ينطوي عليها إدارة معالجات DOM المعقدة من معالجات الأحداث لا تستحق العناء أبدًا. هذا شيء يهدف Backbone.js إلى حله. يعد استخدام Backbone.js للقيام بشيء كهذا خطأ.
الخطأ الثالث: التقليل من تكلفة العرض
نظرًا لأن Backbone.js يجعل من السهل جدًا تقديم وإعادة عرض DOM حسب الرغبة أو استجابةً للأحداث ، فإننا غالبًا ما نتجاهل مدى تأثير ذلك على الأداء العام لتطبيق الويب. هناك العديد من الطرق التي يمكن أن ننتهي من خلالها بسحق طريقة العرض في وجهات نظرنا. في كثير من الأحيان قد لا يبدو هذا كثيرًا ، حيث أصبحت متصفحات الويب الحديثة أجزاء عالية الأداء من البرامج. ولكن مع نمو تطبيقات الويب ، وزيادة كمية البيانات التي يتعامل معها ، يصبح الانخفاض في الأداء أكثر وضوحًا.
يمكننا أن نرى هذا عمليًا من خلال مثال مفتعل حيث نبدأ بمجموعة صغيرة من النماذج ، ونعرض ذلك في عرض القائمة:
var AudioPlayerPlaylist = Backbone.View.extend({ template: _.template('<ul> <% _.each(musics, function(m) { %> <li><%- m.title %></li> <% }) %> </ul>'), initialize: function() { this.listenTo(this.collection, 'add', this.render) }, // ... })في مثال Backbone.js هذا ، نعيد التصيير كلما تمت إضافة نموذج إلى المجموعة. هذا سوف يعمل بشكل جيد. ومع ذلك ، نظرًا لأنه يتم تشغيل حدث "add" في كل مرة يتم فيها إضافة نموذج إلى القائمة ، تخيل جلب قائمة كبيرة من النماذج من الخادم. سيتم استدعاء طريقة التقديم عدة مرات متتالية ، مرة واحدة لكل نموذج في الاستجابة من الخادم. سيكون النموذج الكبير بدرجة كافية كافياً لجعل تطبيقك يتلعثم ويدمر تجربة المستخدم. أحيانًا تكون الاستجابة الصغيرة كافية ، اعتمادًا على مدى تعقيد العرض الذي يتم تقديمه.
حل سريع جدًا لذلك هو ببساطة عدم استدعاء طريقة العرض لكل نموذج تتم إضافته. في مثل هذه الحالات ، ستتم إضافة النماذج دفعة واحدة ، ويمكنك فعل شيء لجعل طريقة العرض تعمل فقط عندما يتم استدعاؤها ولكن لا تتم إعادة استدعاؤها خلال فترة زمنية محددة. تأتي تبعية Backbone.js Underscore.js مع وظيفة مفيدة مفيدة لهذا: “_.debounce”. كل ما تحتاجه للاستفادة من ذلك هو تغيير سطر JavaScript الذي يربط الحدث بهذا:
this.listenTo(this.collection, 'add', _.debounce(_.bind(this.render), 128))سيؤدي هذا إلى إطلاق رد نداء الحدث في كل مرة يحدث فيها حدث "add" ، ومع ذلك ، فإنه سينتظر لمدة 128 مللي ثانية من الحدث الأخير قبل استدعاء طريقة العرض فعليًا.
في معظم الحالات ، سيعتبر هذا بمثابة حل سريع الإصلاح. في الواقع ، هناك طرق أكثر ملاءمة لتجنب التصادم. كتب المطورون وراء Trello ذات مرة منشور مدونة يناقشون تجربتهم ونهجهم في تحسين أداء العرض أثناء استخدام Backbone.js.
الخطأ الرابع: ترك مستمعي الأحداث ملزمين بما يتجاوز استخدامهم
من المحتمل أن يكون ترك مستمعي الأحداث غير المُستخدمين مقيدًا أمرًا يمكن أن يحدث بغض النظر عن إطار عمل JavaScript الذي تستخدمه ، أو إذا كنت تستخدم واحدًا على الإطلاق. على الرغم من أن Backbone.js يجعل من السهل تجنب هذه المشكلة ، فمن المؤكد أنه من الخطأ الاستمرار في ترك ثغرات محتملة لتسرب الذاكرة بسهولة في تطبيق الويب الخاص بك. من المؤكد أن مكون "الحدث" في Backbone.js هو تطبيق رائع للغاية. يسمح لكائنات JavaScript بتنفيذ الميزات المستندة إلى الأحداث بسهولة. نظرًا لأن المشاهدات هي المكان الذي يحدث فيه عادةً معظم استهلاك الأحداث لدينا ، فمن السهل ارتكاب هذا الخطأ هناك:
var AudioPlayerControl = Backbone.View.extend({ initialize: function() { this.model.on('change', _.bind(this.render, this)) // ... }, // ... })لا يختلف سطر ربط الحدث في مقتطف الشفرة هذا كثيرًا عن السطر الموجود في المثال الأول. كل ما فعلناه هنا هو أننا قمنا بتغيير "this.listenTo (this.model ، ...)" إلى "this.model.on (...)". نظرًا لأننا معتادون جدًا على استدعاء ".on ()" لربط الأحداث من تجربتنا مع بعض أطر عمل ومكتبات JavaScript الأخرى ، عندما نبدأ في استخدام Backbone.js ، غالبًا ما نميل إلى استخدام استدعاءات ".on ()" لربط الأحداث. كان من الممكن أن يكون هذا جيدًا ، فقط إذا كلفنا أنفسنا عناء استدعاء ".off ()" لفك ارتباط معالجات الأحداث عندما لا تكون ضرورية. لكننا نادرًا ما نفعل ذلك ، وينتهي به الأمر أن يكون مصدرًا لتسريبات الذاكرة.

يقدم Backbone.js طريقة بسيطة لحل هذه المشكلة. يتم ذلك من خلال استخدام طريقة "object.listenTo ()". يتيح ذلك للكائن الذي تطلبه "listenTo ()" متابعة الأحداث التي يستمع إليها ، وكذلك يجعل من السهل إلغاء ربط كل هذه الأحداث دفعة واحدة. طرق العرض ، على سبيل المثال ، تتوقف تلقائيًا عن الاستماع إلى جميع الأحداث المرتبطة بمجرد استدعاء "إزالة ()" عليها.
الخطأ الخامس: إنشاء طرق عرض متجانسة
إذا فكرت في الأمر ، فإن البساطة في Backbone.js توفر قدرًا هائلاً من المرونة في كيفية تصميم الواجهة الأمامية لتطبيق الويب الخاص بك. نظرًا لأن النماذج والمجموعات والمشاهد هي اللبنات الأساسية لمكوناتك ، فمن الضروري أن تحافظ عليها خفيفة الوزن ومحددة قدر الإمكان. في كثير من الأحيان ، تصبح الآراء هي أثقل جوانب تطبيق الويب الخاص بك من حيث الكود. ولكن من المهم حقًا ألا ينتهي بك الأمر بصنع مناظر متجانسة عملاقة تنتهي بمحاولة القيام بكل ما يقدمه تطبيقك. بدلاً من إنشاء عرض "AudioPlayer" عملاق مع كل المنطق المحشو به ، قسّمه إلى عدد من المشاهدات المنطقية مثل عرض قائمة التشغيل ، وعرض لعناصر التحكم ، وعرض للمتخيل ، وما إلى ذلك. نوع الدقة الذي تريد ضمانه يعتمد على الأرجح على التطبيق الذي تحاول إنشاءه.
هذا لأنه مع طرق العرض الدقيقة ، حيث يقوم كل عرض بشيء محدد ويفعله بشكل صحيح ، يصبح تطوير تطبيق ويب باستخدام Backbone.js أمرًا سهلاً. يجب أن تكون شفرتك أكثر قابلية للصيانة وأن يسهل توسيعها أو تعديلها في المستقبل. ثم هناك الطرف الآخر ، حيث ينتهي بك الأمر إلى المبالغة فيه. تم تصميم طرق عرض Backbone.js لتسهيل العمل مع نموذج أو مجموعة ، ويمكن أن يعمل هذا على الأرجح كتلميح لكيفية هيكلة تطبيقك. شارك إيان ستورم تايلور بعض الأفكار القيمة على مدونته والتي ربما يجب أن تضعها في اعتبارك أثناء تنفيذ الآراء.
الخطأ السادس: عدم إدراك أن Backbone.js يمكن تكييفه مع واجهات برمجة تطبيقات غير مريحة
يعمل Backbone.js مع واجهات برمجة تطبيقات RESTful المستندة إلى JSON خارج الصندوق. كل ما تحتاجه لذلك هو jQuery (أو شيء يمكن أن يكون بديلًا مؤقتًا له ، مثل Zepto). ومع ذلك ، فإن Backbone.js قابل للتوسيع للغاية. في الواقع ، يمكن تكييف Backbone.js لاستخدام أنواع أخرى من واجهات برمجة التطبيقات وأنواع أخرى من تنسيقات التشفير.
مكون Backbone.js الذي يتعامل مع تفاعل الواجهة الأمامية مع خدمات النهاية الخلفية هو "Sync". يكشف هذا المكون عن عدد من السمات التي يمكنك تجاوزها بسهولة لتخصيص طريقة Backbone.js للتفاعل مع نقاط نهاية API. في الواقع ، من الممكن أيضًا استبدال آلية المزامنة الافتراضية بشيء غير تقليدي على أقل تقدير ، مثل استخدام localStorage لاستمرار البيانات ، بدلاً من الخدمات الخلفية.
توجد العديد من المكونات الإضافية التي تسهل تخصيص سلوك مزامنة Backbone.js. على سبيل المثال ، يسمح لك مكون إضافي يسمى Backbone.dualStorage باستخدام كل من خدمات الواجهة الخلفية والتخزين المحلي لاستمرار البيانات. عندما يصبح تطبيقك غير متصل بالإنترنت ، يستخدم المكون الإضافي localStorage للاستمرار في تقديم الطلبات من البيانات المخزنة مؤقتًا ، وتتبع التغييرات التي قد تزامنها مع الخادم لاحقًا عندما تكون متصلاً بالإنترنت.
على الرغم من أن استخدام Backbone.js بنهاية خلفية مصممة لتكون مريحة ومتوافقة معها أسهل في الاستخدام ، إلا أن هذا لا يعني أن Backbone.js يمكن أن يعمل معها. مع بعض التغييرات على آلية مزامنة Backbone.js الافتراضية ، يمكنك تكييفها مع مجموعة واسعة من واجهات برمجة التطبيقات للخدمة الخلفية وتنسيقات التشفير.
من الجدير بالذكر أن الأجزاء الأخرى من Backbone.js مرنة أيضًا ، وهي اختيارية من حيث الشكل. على سبيل المثال ، لا يتعين عليك استخدام محرك القوالب الافتراضي الذي يأتي مع Underscore.js. لا تحتاج حتى إلى استخدام مكون عرض Backbone.js ويمكنك استبداله بشيء آخر تمامًا إذا كنت تريد ذلك.
الخطأ السابع: تخزين البيانات على طرق العرض بدلاً من النماذج
أحد الأخطاء التي قد نرتكبها غالبًا كمبتدئين في تعلم Backbone.js هو تخزين البيانات مباشرة على طرق العرض كسمات. قد تكون هذه البيانات هناك لتتبع بعض الحالات أو بعض تحديد المستخدم. هذا شيء يجب تجنبه.
var AudioPlayerVisualizer = Backbone.View.extend({ events: { 'click .btn-color': function(event) { this.colorHex = $(event.target).data('color-hex') this.render() } }, // ... })يمكنك دائمًا إنشاء بعض النماذج والمجموعات الإضافية بدون نقاط نهاية. يمكن أن تساعدك هذه في تخزين البيانات التي ليس بالضرورة أن تستمر في النهاية الخلفية ، أو قد تكون مؤقتة بطبيعتها. يمنحك تخزينها في النماذج ميزة القدرة على الاستماع للتغييرات. يمكن لوجهة النظر ذات الصلة ، أو حتى وجهات النظر المتعددة ، ملاحظة هذه النماذج وإعادة تقديم نفسها حسب الضرورة.
تخيل أنك قمت بالفعل بتخزين متغيرات تتبع الحالة على طرق العرض وكان عليك استدعاء طريقة العرض في كل مرة تقوم فيها بتغييرها. قد يؤدي فقد استدعاء واحد فقط لطريقة العرض هذه إلى ترك التطبيق في حالة معطلة ، من حيث ما يواجهه المستخدم على الشاشة. علاوة على ذلك ، مع طرق العرض الصغيرة ، قد تضطر إلى مزامنة متغيرات الحالة هذه على كائنات عرض متعددة ثم يتعين عليك استدعاء طريقة العرض عليها أيضًا.
الخطأ الثامن: استخدام jQuery “.on ()” بدلاً من الأحداث المفوضة
لدى Backbone.js ، في رأيي ، طريقة رائعة واحدة للتعامل مع أحداث DOM. عدم استخدامه يشكل مجموعة من العيوب. يمكن أن تبدو وظيفة ربط الأحداث ".on ()" الخاصة بـ jQuery مريحة ، ولكن غالبًا ما تكون صعبة على المدى الطويل. على سبيل المثال ، عند فصل العناصر عن DOM ، يسقط jQuery تلقائيًا جميع معالجات الأحداث المرتبطة بالعناصر باستخدام “.on ()”. هذا يعني أن أي حدث DOM تحاول ربطه من داخل عرض ما سيحتاج إلى الارتداد إذا فصلت عنصر الجذر عن DOM وأعدت توصيله.
var AudioPlayerControls = Backbone.View.extend({ events: { 'click .btn-play, .btn-pause': function() { /* ... */ }, 'click .btn-prev': function() { /* ... */ }, 'click .btn-next': function() { /* ... */ }, 'click .btn-shuffle': function() { /* ... */ }, 'click .btn-repeat': function() { /* ... */ } }, // ... })عندما يتم إعادة إرفاق العنصر المقابل لهذا العرض بـ DOM ، فكل ما عليك فعله هو استدعاء "التفويضات ()" في العرض لربط كل هذه الأحداث.
لاحظ أنه من المهم فهم كيفية ارتباط هذه الأحداث. بدلاً من ربط الحدث بالعناصر المحددة بواسطة المحدد ، يقوم Backbone.js بالفعل بربط معالج الحدث بالعنصر الجذر في طريقة العرض. يعمل هذا بشكل جيد في جميع الحالات تقريبًا ، وفي الواقع يعمل بشكل أفضل لمعظم احتياجاتنا. لا يتطلب تغيير أو استبدال العناصر الفرعية في شجرة DOM الفرعية لطريقة العرض Backbone.js لربط كل حدث مرة أخرى بالعناصر الجديدة. يستمر المستمعون الحاليون في العمل.
ومع ذلك ، فإن هذا يمنع بعض الأحداث من الاستماع إليها. أحد الأمثلة هو المكان الذي قد ترغب في الاستماع إلى أحداث التمرير على "نافذة" أو على عنصر طفل قابل للتمرير. في حالة العناصر الفرعية ، يمكنك إنشاء عرض فرعي لهذا العنصر والتعامل مع الأحداث هناك.
خاتمة
يعد Backbone.js إطارًا مضغوطًا للغاية ولكنه قابل للتوسيع ، وهو خيار ممتاز لتطبيقات الويب التي تتطلب قدرًا كبيرًا من المرونة خلف الكواليس. على عكس أطر عمل مثل Angular.js و Ember.js الموجودة دائمًا لإخبارك بكيفية القيام بما تريد القيام به ، يتراجع Backbone.js خطوة إلى الوراء ويمنحك مجموعة قوية من الأدوات ويتيح لك تحديد كيفية الاستخدام هم. آمل أن يساعدك هذا البرنامج التعليمي Backbone.js للمبتدئين في تجنب بعض أخطاء التطوير الشائعة وبناء شيء رائع باستخدامه.
