Backbone.js



backbone

Backbone.js

Backbone.Events

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

var object = {};

_.extend(object, Backbone.Events);

object.on("alert", function(msg) {
  alert("Triggered " + msg);
});

object.trigger("alert", "an event");

على سبيل المثال ، لجعل مرسل حدث مفيد يمكن تنسيق الأحداث بين مناطق مختلفة من التطبيق الخاص بك: var dispatcher = _.clone(Backbone.Events)

على object.on(event, callback, [context]) الاسم المستعار: ربط
ربط وظيفة رد اتصال إلى كائن. سيتم استدعاء رد الاتصال عندما يتم إطلاق الحدث . إذا كان لديك عدد كبير من الأحداث المختلفة على الصفحة ، فإن الاتفاقية هي استخدام colons لمساحة الاسم: "poll:start" ، أو "change:selection" . قد تكون سلسلة الحدث أيضًا قائمة مفصولة بفراغات لعدة أحداث ...

book.on("change:title change:author", ...);

سيتم تشغيل عمليات رد الاتصال المرتبطة بالحدث "all" الخاص عند حدوث أي حدث ، ويتم تمرير اسم الحدث باعتباره الوسيطة الأولى. على سبيل المثال ، لتوكيل جميع الأحداث من كائن إلى آخر:

proxy.on("all", function(eventName) {
  object.trigger(eventName);
});

تدعم جميع أساليب أحداث العمود الفقري أيضًا بنية خريطة حدث ، كبديل لوسائل الموقع:

book.on({
  "change:author": authorPane.update,
  "change:title change:subtitle": titleView.update,
  "destroy": bookView.remove
});

لتوفير قيمة سياق this عند استدعاء رد الاتصال ، قم بتمرير الوسيطة الأخيرة الاختيارية: model.on('change', this.render, this) أو model.on({change: this.render}, this) .

off object.off([event], [callback], [context]) Alias: unbind
قم بإزالة وظيفة معاودة الاتصال من الكائن. في حالة عدم تحديد سياق ، ستتم إزالة جميع إصدارات معاودة الاتصال مع سياقات مختلفة. إذا لم يتم تحديد رد اتصال ، فستتم إزالة جميع عمليات معاودة الاتصال للحدث . إذا لم يتم تحديد أي حدث ، فستتم إزالة عمليات رد الاتصال لجميع الأحداث.

// Removes just the `onChange` callback.
object.off("change", onChange);

// Removes all "change" callbacks.
object.off("change");

// Removes the `onChange` callback for all events.
object.off(null, onChange);

// Removes all callbacks for `context` for all events.
object.off(null, null, context);

// Removes all callbacks on `object`.
object.off();

لاحظ أن استدعاء model.off() ، على سبيل المثال ، سيزيل بالفعل جميع الأحداث في النموذج - بما في ذلك الأحداث التي يستخدمها Backbone لمسك الدفاتر الداخلي.

trigger object.trigger(event, [*args])
استدعاءات الاستدعاء للحدث المعني ، أو قائمة أحداث محددة بفراغات. سيتم تمرير الوسيطات اللاحقة للتشغيل إلى معاودة الاتصال.

مرة واحدة object.once(event, callback, [context])
تمامًا كما يحدث ، ولكن يؤدي إلى معاودة الاتصال المنبثقة مرة واحدة فقط قبل إزالتها. سهل القول "في المرة التالية التي يحدث فيها X ، افعل هذا". عندما يتم تمرير أحداث متعددة باستخدام بناء الجملة المفصول ، سيتم إطلاق الحدث مرة واحدة لكل حدث تم تمريره فيه ، وليس مرة واحدة لمجموعة من جميع الأحداث

listenTo object.listenTo(other, event, callback)
أخبر كائن للاستماع إلى حدث معين على كائن آخر. ميزة استخدام هذا النموذج ، بدلاً من other.on(event, callback, object) ، هو أن listenTo يسمح للكائن بتتبع الأحداث ، ويمكن إزالتها مرة واحدة في وقت لاحق. سيتم استدعاء معاودة الاتصال دائمًا باستخدام كائن كسياق.

view.listenTo(model, 'change', view.render);

stopListening object.stopListening([other], [event], [callback])
أخبر كائنًا يتوقف عن الاستماع إلى الأحداث. إما إيقاف الاتصالتستثني بدون أي وسيطات لجعل الكائن يزيل جميع عمليات الاسترجاع registered الخاصة به ... أو يكون أكثر دقة بإخباره فقط بإزالة الأحداث التي يستمع إليها على كائن معين ، أو حدث معين ، أو مجرد رد اتصال محدد.

view.stopListening();

view.stopListening(model);

listenToOnce object.listenToOnce(other, event, callback)
تمامًا مثل registered ، ولكن يؤدي إلى معاودة الاتصال registered مرة واحدة فقط قبل إزالتها.

كتالوج للأحداث
إليك قائمة كاملة من أحداث Backbone المضمنة ، مع الحجج. أنت أيضًا مطلق الحرية في إطلاق الأحداث الخاصة بك في النماذج والمجموعات ومرات المشاهدة كما تراه مناسبًا. يختلط كائن Backbone نفسه في Events ، ويمكن استخدامه لإصدار أي أحداث عالمية يحتاجها التطبيق الخاص بك.

  • "إضافة" (نموذج ، مجموعة ، خيارات) - عند إضافة نموذج إلى مجموعة.
  • "إزالة" (نموذج ، مجموعة ، خيارات) - عند إزالة نموذج من مجموعة.
  • "التحديث" (التجميع ، الخيارات) - حدث واحد يتم تشغيله بعد إضافة أو إزالة أي عدد من النماذج من مجموعة.
  • "إعادة التعيين" (مجموعة ، خيارات) - عند reset محتويات المجموعة بالكامل.
  • "الفرز" (مجموعة ، خيارات) - عند إعادة تصنيف المجموعة.
  • "تغيير" (طراز ، خيارات) - عند تغيير سمات النموذج.
  • "change: [attribute]" (النموذج ، القيمة ، الخيارات) - عند تحديث سمة معينة.
  • "تدمير" (نموذج ، مجموعة ، خيارات) - عندما يتم destroyed نموذج.
  • "request" (model_or_collection، xhr، options) - عند بدء نموذج أو مجموعة طلبًا إلى الخادم.
  • "sync" (model_or_collection ، أو الاستجابة ، أو الخيارات) - عندما تتم مزامنة نموذج أو مجموعة بنجاح مع الخادم.
  • "خطأ" (model_or_collection ، استجابة ، خيارات) - عند فشل طلب نموذج أو مجموعة إلى الخادم.
  • "غير صالح" (نموذج ، خطأ ، خيارات) - عند فشل validation من validation النموذج على العميل.
  • "route: [name]" (params) - يتم تشغيله بواسطة جهاز التوجيه عند مطابقة مسار معين.
  • "route" (route، params) - يتم تشغيله بواسطة جهاز التوجيه عند مطابقة أي مسار.
  • "الطريق" (جهاز التوجيه ، الطريق ، المعلمات) - تم إطلاقه من قبل التاريخ عند مطابقة أي مسار.
  • "الكل" - يتم إطلاق هذا الحدث الخاص لأي حدث تم تشغيله ، ويمرر اسم الحدث باعتباره أول وسيطة متبوعة بكل الحجج المشغلة.

بوجهٍ عام ، عند استدعاء وظيفة تنشر حدثًا ( model.set و collection.add وما إلى ذلك ...) ، إذا كنت ترغب في منع تشغيل الحدث ، فيمكنك تمرير {silent: true} كـ خيار. لاحظ أنه من النادر أن تكون هذه فكرة جيدة. إن التمرير عبر علامة محددة في الخيارات الخاصة بمراجعة معاودة الحدث الخاصة بك ، واختيار تجاهلها ، عادة ما يعمل بشكل أفضل.

Backbone.Model

تمثل النماذج قلب أي تطبيق من تطبيقات جافا سكريبت التي تحتوي على البيانات التفاعلية بالإضافة إلى جزء كبير من المنطق المحيط بها: التحويلات ، وعمليات التحقق ، والخصائص المحسوبة ، والتحكم في الوصول. يمكنك توسيع Backbone.Model مع الأساليب الخاصة بك المجال ، ويوفر نموذج مجموعة أساسية من الوظائف لإدارة التغييرات.

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

var Sidebar = Backbone.Model.extend({
  promptColor: function() {
    var cssColor = prompt("Please enter a CSS color:");
    this.set({color: cssColor});
  }
});

window.sidebar = new Sidebar;

sidebar.on('change:color', function(model, color) {
  $('#sidebar').css({background: color});
});

sidebar.set({color: 'white'});

sidebar.promptColor();

Backbone.Model.extend(properties, [classProperties])
لإنشاء فئة نموذجية خاصة بك ، يمكنك توسيع Backbone.Model وتوفير خصائص المثيل ، بالإضافة إلى classProperties الاختياري ليتم إرفاقه مباشرة بوظيفة المُنشئ.

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

var Note = Backbone.Model.extend({

  initialize: function() { ... },

  author: function() { ... },

  coordinates: function() { ... },

  allowedToEdit: function(account) {
    return true;
  }

});

var PrivateNote = Note.extend({

  allowedToEdit: function(account) {
    return account.owns(this);
  }

});

ضع جانباً على وجه super : لا تقدم JavaScript طريقة بسيطة للاتصال بالمؤسسة - وهي الدالة التي تحمل الاسم نفسه المحدد في سلسلة النموذج الأولي. إذا قمت بتجاوز وظيفة أساسية ، مثل set ، أو save ، وتريد استدعاء تطبيق الكائن الرئيسي ، فستضطر إلى الاتصال به صراحة ، عبر هذه السطور:

var Note = Backbone.Model.extend({
  set: function(attributes, options) {
    Backbone.Model.prototype.set.apply(this, arguments);
    ...
  }
});

منشئ / تهيئة new Model([attributes], [options])
عند إنشاء مثيل لنموذج ، يمكنك تمرير القيم الأولية للسمات ، والتي سيتم set على النموذج. إذا قمت بتحديد وظيفة تهيئة ، فسيتم استدعاءها عند إنشاء النموذج.

new Book({
  title: "One Thousand and One Nights",
  author: "Scheherazade"
});

في حالات نادرة ، إذا كنت ترغب في الحصول على فكرة رائعة ، فقد تحتاج إلى تجاوز المُنشئ ، والذي يسمح لك باستبدال وظيفة المنشئ الفعلية لطرازك.

var Library = Backbone.Model.extend({
  constructor: function() {
    this.books = new Books();
    Backbone.Model.apply(this, arguments);
  },
  parse: function(data, options) {
    this.books.reset(data.books);
    return data.library;
  }
});

إذا قمت بتمرير {collection: ...} كخيارات ، فسيقوم النموذج باكتساب خاصية collection سيتم استخدامها لتوضيح المجموعة التي ينتمي إليها النموذج ، ويتم استخدامها للمساعدة في حساب url الخاص بالنموذج. عادة ما يتم إنشاء خاصية model.collection تلقائيًا عند إضافة نموذج إلى مجموعة أولاً. لاحظ أن العكس ليس صحيحًا ، لأن تمرير هذا الخيار إلى المنشئ لن يؤدي تلقائيًا إلى إضافة النموذج إلى المجموعة. مفيد ، في بعض الأحيان.

إذا تم تمرير {parse: true} كخيار ، فسيتم أولاً تحويل السمات عن طريق parse قبل set على النموذج.

احصل على model.get(attribute)
احصل على القيمة الحالية لسمة من النموذج. على سبيل المثال: note.get("title")

set model.set(attributes, [options])
عيّن تجزئة لسمات (واحد أو كثير) في النموذج. إذا غيّرت أي من السمات حالة النموذج ، فسيتم تشغيل حدث "change" في النموذج. يتم أيضًا تشغيل تغيير الأحداث لسمات محددة ، ويمكنك الربط بينها أيضًا ، على سبيل المثال: change:title ، change:content . يمكنك أيضًا تمرير مفاتيح وقيم فردية.

note.set({title: "March 20", content: "In his eyes she eclipses..."});

book.set("title", "A Scandal in Bohemia");

الهروب model.escape(attribute)
يشبه get ، ولكنه يعرض الإصدار الذي تم تخطيه بواسطة HTML لسمات النموذج. إذا كنت تقوم باستكمال البيانات من النموذج إلى HTML ، فسيؤدي استخدام ميزة الهروب لاسترداد السمات إلى منع هجمات XSS .

var hacker = new Backbone.Model({
  name: "<script>alert('xss')</script>"
});

alert(hacker.escape('name'));

has model.has(attribute)
إرجاع true إذا تم تعيين السمة إلى قيمة غير خالية أو غير معرفة.

if (note.has("title")) {
  ...
}

unset model.unset(attribute, [options])
أزل سمة عن طريق حذفها من تجزئة السمات الداخلية. إطلاق حدث "change" ما لم يتم تمرير silent كخيار.

clear model.clear([options])
يزيل كل السمات من النموذج ، بما في ذلك سمة id . إطلاق حدث "change" ما لم يتم تمرير silent كخيار.

id model.id
خاصية خاصة من الموديلات ، المعرف عبارة عن سلسلة عشوائية (معرف صحيح أو UUID). إذا قمت بتعيين المعرّف في تجزئة السمات ، فسيتم نسخه في النموذج كخاصية مباشرة. يمكن استرداد النماذج حسب المعرفات من المجموعات ، ويتم استخدام المعرف لإنشاء نماذج عناوين URL بشكل افتراضي.

idAttribute model.idAttribute
يتم تخزين المعرف الفريد الخاص بالنموذج تحت سمة id . إذا كنت تتصل مباشرة مع الخلفية (CouchDB ، MongoDB) التي تستخدم مفتاحًا فريدًا مختلفًا ، فيمكنك تعيين idAttribute ليتم idAttribute بشفافية من هذا المفتاح إلى id .

var Meal = Backbone.Model.extend({
  idAttribute: "_id"
});

var cake = new Meal({ _id: 1, name: "Cake" });
alert("Cake id: " + cake.id);

cid model.cid
خاصية خاصة من الموديلات أو معرّف cid أو العميل هو معرّف فريد يتم تعيينه تلقائيًا لجميع الطُرز عند إنشائها لأول مرة. تكون معرفات العميل سهلة الاستخدام عندما لم يتم حفظ النموذج بعد في الخادم ، ولا يتوفر له معرفه الحقيقي في النهاية ، ولكن يلزم بالفعل أن يكون مرئيًا في واجهة المستخدم.

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

الرجاء استخدام set لتحديث السمات بدلاً من تعديلها مباشرة. إذا كنت ترغب في استرداد نسخة من خصائص النموذج _.clone(model.attributes) ، فاستخدم _.clone(model.attributes) بدلاً من ذلك.

نظرًا لحقيقة أن Events تقبل قوائم الأحداث المنفصلة عن الفضاء ، يجب ألا تتضمن أسماء السمات مسافات.

تغيير model.changed
الخاصية المتغيرة هي التجزئة الداخلية التي تحتوي على جميع السمات التي تغيرت منذ آخر set . يرجى عدم تحديث التحديث مباشرة حيث يتم الحفاظ على حالته داخليًا بواسطة set . يمكن الحصول على changedAttributes من changedAttributes من changedAttributes .

defaults model.defaults or model.defaults()
يمكن استخدام التجزئة الافتراضي (أو الوظيفة) لتحديد السمات الافتراضية لطرازك. عند إنشاء مثيل للنموذج ، سيتم تعيين أي سمات غير محددة إلى قيمتها الافتراضية.

var Meal = Backbone.Model.extend({
  defaults: {
    "appetizer":  "caesar salad",
    "entree":     "ravioli",
    "dessert":    "cheesecake"
  }
});

alert("Dessert will be " + (new Meal).get('dessert'));

تذكر أنه في JavaScript ، يتم تمرير الكائنات حسب المرجع ، لذلك إذا قمت بتضمين كائن كقيمة افتراضية ، فسيتم مشاركته بين جميع الحالات. بدلاً من ذلك ، قم بتعريف الإعدادات الافتراضية كدالة.

toJSON model.toJSON([options])
قم بإرجاع نسخة ضحلة من attributes الطراز لتضمين JSON. يمكن استخدام هذا للاستمرار أو التسلسل أو لزيادة قبل إرسالها إلى الخادم. يعد اسم هذه الطريقة مربكًا بعض الشيء ، حيث إنه لا يعرض فعليًا سلسلة JSON - ولكن أخشى أن تكون الطريقة التي تعمل بها واجهة برمجة تطبيقات جافا سكريبت JSON.stringify .

var artist = new Backbone.Model({
  firstName: "Wassily",
  lastName: "Kandinsky"
});

artist.set({birthday: "December 16, 1866"});

alert(JSON.stringify(artist));

sync model.sync(method, model, [options])
يستخدم Backbone.sync حالة طراز إلى الخادم. يمكن تجاوزها لسلوك مخصص.

fetch model.fetch([options])
يدمج حالة النموذج مع السمات التي تم جلبها من الخادم عن طريق تفويض إلى Backbone.sync . jqXHR . من المفيد إذا لم يتم ملء النموذج بالبيانات ، أو إذا كنت ترغب في التأكد من أن لديك أحدث حالة للخادم. يؤدي إلى حدث "change" إذا كانت حالة الخادم تختلف عن السمات الحالية. يقبل fetch success (model, response, options) error في تجزئة الخيارات ، والتي يتم تمريرها (model, response, options) كوسيطة.

// Poll every 10 seconds to keep the channel model up-to-date.
setInterval(function() {
  channel.fetch();
}, 10000);

save model.save([attributes], [options])
حفظ نموذج لقاعدة البيانات الخاصة بك (أو طبقة الاستمرار البديلة) ، عن طريق التفويض إلى Backbone.sync . jqXHR إذا كان التحقق من الصحة ناجحًا jqXHR . يجب أن تحتوي سمات التجزئة (كما في set ) على السمات التي ترغب في تغييرها - لن يتم تبديل المفاتيح التي لم يتم ذكرها - ولكن سيتم إرسال تمثيل كامل للمورد إلى الخادم. كما هو الحال مع set ، يمكنك تمرير مفاتيح وقيم فردية بدلاً من التجزئة. إذا كان للطراز طريقة تحقق ، وفشل التحقق من الصحة ، فلن يتم حفظ النموذج. إذا كان النموذج isNew ، فسيكون الحفظ "create" (HTTP POST ) ، إذا كان النموذج موجودًا بالفعل على الخادم ، فسيكون الحفظ "update" (HTTP PUT ).

إذا كنت بدلاً من ذلك ، ترغب فقط في إرسال السمات التي تم تغييرها إلى الخادم ، call model.save(attrs, {patch: true}) . ستحصل على طلب HTTP PATCH إلى الخادم مع السمات التي تم تمريرها فقط.

سيتسبب استدعاء save بسمات جديدة في حدوث حدث "change" فورًا ، وحدث "request" نظرًا لأن طلب Ajax يبدأ بالانتقال إلى الخادم ، وحدث "sync" بعد أن اعترف الخادم بالتغيير الناجح. مرر {wait: true} إذا كنت تريد انتظار الخادم قبل تعيين السمات الجديدة في النموذج.

في المثال التالي ، لاحظ كيف يتلقى Backbone.sync من Backbone.sync طلب "create" في المرة الأولى التي يتم فيها حفظ النموذج وطلب "update" للمرة الثانية.

Backbone.sync = function(method, model) {
  alert(method + ": " + JSON.stringify(model));
  model.set('id', 1);
};

var book = new Backbone.Model({
  title: "The Rough Riders",
  author: "Theodore Roosevelt"
});

book.save();

book.save({author: "Teddy"});

حفظ يقبل الاستعادة الناجحة error في تجزئة الخيارات ، والذي سيتم تمرير الحجج (model, response, options) . إذا فشل التحقق من صحة جانب الخادم ، فأرجع رمز استجابة HTTP غير 200 ، إلى جانب استجابة خطأ في النص أو JSON.

book.save("author", "F.D.R.", {error: function(){ ... }});

تدمير model.destroy([options])
يدمر النموذج على الخادم بتفويض طلب HTTP DELETE إلى Backbone.sync . إرجاع كائن jqXHR ، أو false إذا كان النموذج isNew . يقبل الاستعادة الناجحة error في تجزئة الخيارات ، والتي سيتم تمريرها (model, response, options) . يُشغِّل حدثًا "destroy" على النموذج ، والذي سيشاهد من خلال أي مجموعات تحتوي عليه ، وحدث "request" عندما يبدأ طلب Ajax إلى الخادم ، وحدث "sync" ، بعد أن أقر الخادم بنجاح حذف النموذج. مرر {wait: true} إذا كنت تريد الانتظار حتى يستجيب الخادم قبل إزالة النموذج من المجموعة.

book.destroy({success: function(model, response) {
  ...
}});

الطرق Underscore (9)
تعمل الوكلاء الأساسيين في Underscore.js لتوفير 9 وظائف للكائن على Backbone.Model . لم يتم توثيقها جميعًا هنا ، ولكن يمكنك إلقاء نظرة على وثائق Underscore للحصول على التفاصيل الكاملة ...

user.pick('first_name', 'last_name', 'email');

chapters.keys().join(', ');

التحقق من صحة model.validate(attributes, options)
يتم ترك هذه الطريقة غير محددة ويتم تشجيعك على تجاوزها بأي منطق تحقق خاص بك يمكنك تنفيذه في JavaScript. بشكل افتراضي ، قم save التحقق من الشيكات قبل تعيين أي سمات ولكنك قد تخبر أيضًا set على التحقق من السمات الجديدة بتمرير {validate: true} كخيار.
يتلقى أسلوب التحقق سمات الطراز وكذلك أي خيارات تم تمريرها set أو save . إذا كانت الصفات صالحة ، فلا ترجع أي شيء من التحقق ؛ إذا كانت غير صالحة ، فارجع خطأ من اختيارك. يمكن أن تكون بسيطة مثل رسالة خطأ سلسلة ليتم عرضها ، أو كائن خطأ كامل يصف الخطأ برمجيا. إذا كان التحقق من الصحة يؤدي إلى ظهور خطأ ، فلن يستمر save ولن يتم تعديل سمات الطراز على الخادم. تؤدي عمليات التحقق من الصحة الفاشلة إلى تشغيل حدث "invalid" ، وتعيين خاصية validationError في النموذج بالقيمة التي يتم إرجاعها بواسطة هذه الطريقة.

var Chapter = Backbone.Model.extend({
  validate: function(attrs, options) {
    if (attrs.end < attrs.start) {
      return "can't end before it starts";
    }
  }
});

var one = new Chapter({
  title : "Chapter One: The Beginning"
});

one.on("invalid", function(model, error) {
  alert(model.get("title") + " " + error);
});

one.save({
  start: 15,
  end:   10
});

تعتبر الأحداث "invalid" مفيدة في توفير رسائل خطأ حبيبية على مستوى النموذج أو المجموعة.

validationError model.validationError
القيمة التي يتم إرجاعها عن طريق validation من الصحة أثناء آخر عملية التحقق من الصحة.

isValid model.isValid()
قم بتشغيل validation للتحقق من حالة النموذج.

var Chapter = Backbone.Model.extend({
  validate: function(attrs, options) {
    if (attrs.end < attrs.start) {
      return "can't end before it starts";
    }
  }
});

var one = new Chapter({
  title : "Chapter One: The Beginning"
});

one.set({
  start: 15,
  end:   10
});

if (!one.isValid()) {
  alert(one.get("title") + " " + one.validationError);
}

url model.url()
لعرض عنوان URL النسبي حيث سيكون مصدر النموذج موجودًا على الخادم. إذا كانت النماذج الخاصة بك موجودة في مكان آخر ، فقم بتجاوز هذه الطريقة باستخدام المنطق الصحيح. يولد عناوين URL للنموذج: "[collection.url]/[id]" بشكل افتراضي ، ولكن يمكنك تجاوز ذلك بتحديد urlRoot صريح إذا كان يجب ألا تؤخذ مجموعة النموذج بعين الاعتبار.

يقوم المندوبون إلى Collection#url بتوليد عنوان URL ، لذلك تأكد من أنه قد تم تحديده أو خاصية urlRoot ، إذا كانت جميع نماذج هذه الفئة تتشارك في عنوان URL أساسي شائع. هناك نموذج له معرف 101 ، مخزّن في Backbone.Collection مع url لـ "/documents/7/notes" ، سيكون له عنوان URL هذا: "/documents/7/notes/101"

urlRoot model.urlRoot or model.urlRoot()
حدد urlRoot إذا كنت تستخدم نموذجًا خارج مجموعة ، لتمكين وظيفة url الافتراضية لإنشاء عناوين URL استنادًا إلى معرف النموذج. "[urlRoot]/id"
عادة ، لن تحتاج إلى تحديد هذا. لاحظ أن urlRoot قد يكون أيضًا وظيفة.

var Book = Backbone.Model.extend({urlRoot : '/books'});

var solaris = new Book({id: "1083-lem-solaris"});

alert(solaris.url());

model.parse(response, options)
يسمى التحليل كلما تم إرجاع بيانات النموذج من قبل الخادم ، في fetch ، save . يتم تمرير الدالة كائن response الأولية ثم يجب إرجاع تجزئة سمات set على الطراز. التطبيق الافتراضي هو a-op ، يمر ببساطة عبر استجابة JSON. يمكنك تجاوز هذا إذا كنت بحاجة إلى العمل باستخدام واجهة برمجة تطبيقات موجودة مسبقًا ، أو مساحة اسم أفضل لاستجاباتك.

إذا كنت تعمل مع خلفية Rails الخلفية التي تحتوي على إصدار سابق لـ 3.1 ، فستلاحظ أن تطبيق to_json الافتراضي يتضمن سمات النموذج تحت مساحة الاسم. لتعطيل هذا السلوك من أجل دمج Backbone السلس ، اضبط:

ActiveRecord::Base.include_root_in_json = false

clone model.clone()
لعرض نسخة جديدة من النموذج بسمات متطابقة.

isNew model.isNew()
هل تم حفظ هذا النموذج للخادم حتى الآن؟ إذا كان النموذج لا يحتوي على id ، فإنه يعتبر جديدًا.

تم تغيير موديل model.hasChanged([attribute])
هل تغير النموذج منذ آخر set ؟ إذا تم تمرير سمة ، ترجع true إذا تم تغيير تلك السمة المحددة.

لاحظ أن هذه الطريقة ، والطرق ذات الصلة بالتغيير التالية ، تكون مفيدة فقط خلال مسار "change" .

book.on("change", function() {
  if (book.hasChanged("title")) {
    ...
  }
});

changedAttributes model.changedAttributes([attributes])
استرداد تجزئة لسمات النموذج فقط التي تغيرت منذ آخر set ، أو false إذا لم false هناك. اختياريًا ، يمكن تمرير تجزئة سمات خارجية ، وإرجاع السمات في تلك التجزئة والتي تختلف عن النموذج. يمكن استخدام هذا لمعرفة أي جزء من عرض يجب تحديثه ، أو ما يجب إجراء المكالمات لمزامنة التغييرات على الخادم.

model.previous(attribute) السابق. السابق model.previous(attribute)
أثناء حدث "change" ، يمكن استخدام هذه الطريقة للحصول على القيمة السابقة للسمة التي تم تغييرها.

var bill = new Backbone.Model({
  name: "Bill Smith"
});

bill.on("change:name", function(model, name) {
  alert("Changed name from " + bill.previous("name") + " to " + name);
});

bill.set({name : "Bill Jones"});

previousAttributes model.previousAttributes()
قم بإرجاع نسخة من السمات السابقة للنموذج. من المفيد الحصول على فرق بين إصدارات النموذج ، أو العودة إلى حالة صحيحة بعد حدوث خطأ.

Backbone.Collection

يتم طلب المجموعات مجموعات من النماذج. يمكنك ربط أحداث "change" ليتم إعلامك عند تعديل أي طراز في المجموعة ، والاستماع إلى أحداث "add" و "remove" ، fetch المجموعة من الخادم ، واستخدام مجموعة كاملة من أساليب Underscore.js .

سيتم أيضًا تشغيل أي حدث يتم تشغيله على طراز في مجموعة في المجموعة مباشرةً ، من أجل الراحة. يسمح لك هذا بالاستماع إلى التغييرات التي تطرأ على سمات محددة في أي نموذج في مجموعة ، على سبيل المثال: documents.on("change:selected", ...)

Backbone.Collection.extend(properties, [classProperties])
لإنشاء فئة تجميع خاصة بك ، قم بتوسيع Backbone.Collection ، مع توفير خصائص المثيل ، بالإضافة إلى classProperties الاختياري ليتم إرفاقه مباشرة بوظيفة منشئ المجموعة.

model collection.model([attrs], [options])
تجاوز هذه الخاصية لتحديد فئة النموذج التي تحتوي على المجموعة. إذا تم تعريفها ، فيمكنك تمرير كائنات الخصائص الأولية (والمصفوفات) add ، create ، وإعادة reset ، وسيتم تحويل السمات إلى نموذج من النوع المناسب.

var Library = Backbone.Collection.extend({
  model: Book
});

يمكن أن تحتوي المجموعة أيضًا على نماذج متعددة الأشكال بتجاوز هذه الخاصية مع مُنشئ يُرجع نموذجًا.

var Library = Backbone.Collection.extend({

  model: function(attrs, options) {
    if (condition) {
      return new PublicDocument(attrs, options);
    } else {
      return new PrivateDocument(attrs, options);
    }
  }

});

modelId collection.modelId(attrs)
تجاوز هذا الأسلوب لإرجاع القيمة التي ستستخدمها المجموعة لتعريف نموذج معين وفقًا لخصائصه. من المفيد دمج النماذج من جداول متعددة مع قيم idAttribute مختلفة في مجموعة واحدة.

افتراضيًا ، تُرجع قيمة idAttribute من فئة نموذج المجموعة أو فشل ذلك ، id . إذا كانت مجموعتك تستخدم مصنعًا نموذجيًا idAttribute النماذج idAttribute بخلاف id فيجب عليك تجاوز هذه الطريقة.

var Library = Backbone.Collection.extend({
  modelId: function(attrs) {
    return attrs.type + attrs.id;
  }
});

var library = new Library([
  {type: 'dvd', id: 1},
  {type: 'vhs', id: 1}
]);

var dvdId = library.get('dvd1').id;
var vhsId = library.get('vhs1').id;
alert('dvd: ' + dvdId + ', vhs: ' + vhsId);

منشئ / تهيئة new Backbone.Collection([models], [options])
عند إنشاء مجموعة ، يمكنك اختيار المرور في المصفوفة الأولية للنماذج . قد يتم تضمين comparator المجموعة كخيار. سيؤدي تمرير false كخيار مقارنة إلى منع الفرز. إذا قمت بتعريف وظيفة تهيئة ، فسيتم استدعاءها عند إنشاء المجموعة. هناك عدة خيارات ، إذا ما تم توفيرها ، مرتبطة بالمجموعة مباشرة: model comparator .
قم بالتمرير options لإنشاء مجموعة فارغة تحتوي على options .

var tabs = new TabSet([tab1, tab2, tab3]);
var spaces = new Backbone.Collection(null, {
  model: Space
});

نماذج collection.models
الوصول الخام إلى مجموعة جافا سكريبت من الموديلات داخل المجموعة. عادةً ما ستحتاج إلى استخدام ، أو at ، أو طرق Underscore للوصول إلى كائنات نموذجية ، ولكن في بعض الأحيان يكون المطلوب مرجع مباشر إلى الصفيف.

toJSON collection.toJSON([options])
قم toJSON صفيف يحتوي على تجزئة سمات كل طراز (عبر toJSON ) في المجموعة. يمكن استخدام هذا لإجراء تسلسل واستمرار المجموعة ككل. يعد اسم هذه الطريقة مربكًا بعض الشيء ، لأنه يتوافق مع واجهة برمجة تطبيقات JSON JavaScript .

var collection = new Backbone.Collection([
  {name: "Tim", age: 5},
  {name: "Ida", age: 26},
  {name: "Rob", age: 55}
]);

alert(JSON.stringify(collection));

sync collection.sync(method, collection, [options])
يستخدم Backbone.sync حالة مجموعة إلى الخادم. يمكن تجاوزها لسلوك مخصص.

الطرق السفلية (46)
تعمل الوكلاء الأساسيين في Underscore.js على توفير 46 وظيفة تكرار على Backbone.Collection . لم يتم توثيقها جميعًا هنا ، ولكن يمكنك إلقاء نظرة على وثائق Underscore للحصول على التفاصيل الكاملة ...

يمكن أن تأخذ معظم أساليب كائن أو سلسلة لدعم المسندات نمط - سمة - نمط أو دالة يتلقى مثيل نموذج كوسيطة.

books.each(function(book) {
  book.publish();
});

var titles = books.map("title");

var publishedBooks = books.filter({published: true});

var alphabetical = books.sortBy(function(book) {
  return book.author.get("name").toLowerCase();
});

var randomThree = books.sample(3);

add collection.add(models, [options])
إضافة نموذج (أو مجموعة من الطرز) إلى المجموعة ، وإطلاق حدث "add" لكل طراز ، وحدث "update" بعد ذلك. إذا تم تعريف خاصية نموذج ، فيجوز لك أيضًا تمرير كائنات السمات الأولية ، وإظهارها كأنماط من النموذج. إرجاع النماذج المضافة (أو الموجودة مسبقًا ، إذا كانت مكررة). مرر {at: index} لدمج النموذج في المجموعة في index المحدد. إذا كنت تضيف نماذج إلى المجموعة الموجودة بالفعل في المجموعة ، فسيتم تجاهلها ، ما لم تمر {merge: true} ، وفي هذه الحالة سيتم دمج سماتها في النماذج المقابلة ، مع إطلاق أي "change" مناسب الأحداث.

var ships = new Backbone.Collection;

ships.on("add", function(ship) {
  alert("Ahoy " + ship.get("name") + "!");
});

ships.add([
  {name: "Flying Dutchman"},
  {name: "Black Pearl"}
]);

لاحظ أن إضافة النموذج نفسه (نموذج له نفس id ) إلى مجموعة أكثر من مرة
هو لا.

إزالة collection.remove(models, [options])
قم بإزالة نموذج (أو مجموعة من الطرز) من المجموعة وإعادتها. يمكن أن يكون كل نموذج نسخة نموذجية أو سلسلة id أو كائن JS ، أي قيمة مقبولة كوسيطة id من collection.get . إطلاق حدث "remove" لكل نموذج ، وحدث "update" واحد بعد ذلك ، ما لم يتم تمرير {silent: true} . يتوفر فهرس النموذج قبل الإزالة للمستمعين كـ options.index .

reset collection.reset([models], [options])
تعد إضافة وإزالة النماذج في وقت واحد أمرًا جيدًا وجيدًا ، ولكن في بعض الأحيان يكون لديك العديد من النماذج لتغييرها ، فأنت تفضل بدلاً من ذلك تحديث المجموعة بشكل مجمّع. استخدم إعادة التعيين لاستبدال المجموعة بقائمة جديدة من الطُرز (أو تجزئات السمة) ، مما يؤدي إلى بدء حدث "reset" واحد عند الانتهاء ، ودون تشغيل أي إضافة أو إزالة أحداث في أي طرازات. إرجاع الطرازات التي تم تعيينها مؤخرًا. لراحتك ، ضمن حدث "reset" ، تتوفر قائمة أي طرازات سابقة على هيئة options.previousModels .
قم بالتمرير options لإفراغ مجموعتك options .

في ما يلي مثال على ذلك باستخدام إعادة تعيين لتكوين مجموعة عمليات أثناء تحميل الصفحة الأولي ، في تطبيق Rails:

<script>
  var accounts = new Backbone.Collection;
  accounts.reset(<%= @accounts.to_json %>);
</script>

سوف calling collection.reset() دون تمرير أي نماذج كوسائط تفريغ المجموعة بأكملها.

set collection.set(models, [options])
يقوم الأسلوب set بتحديث "ذكية" للمجموعة باستخدام قائمة النماذج التي تم تمريرها. إذا لم يكن أحد النماذج في القائمة موجودًا بعد في المجموعة ، فسيتم إضافته ؛ إذا كان النموذج موجودًا بالفعل في المجموعة ، فسيتم دمج سماته ؛ وإذا كانت المجموعة تحتوي على أي طرازات غير موجودة في القائمة ، فستتم إزالتها. يتم تشغيل جميع الأحداث المناسبة "add" و "remove" و "change" عند حدوث ذلك. إرجاع النماذج التي تم لمسها في المجموعة. إذا كنت ترغب في تخصيص السلوك ، فيمكنك تعطيله باستخدام خيارات: {add: false} أو {remove: false} أو {merge: false} .

var vanHalen = new Backbone.Collection([eddie, alex, stone, roth]);

vanHalen.set([eddie, alex, stone, hagar]);

// Fires a "remove" event for roth, and an "add" event for "hagar".
// Updates any of stone, alex, and eddie's attributes that may have
// changed over the years.

احصل على collection.get(id)
احصل على نموذج من مجموعة محددة بواسطة id ، أو cid ، أو بتمرير نموذج .

var book = library.get(110);

في collection.at(index)
احصل على نموذج من مجموعة محددة بواسطة الفهرس. من المفيد إذا تم تجميع المجموعة الخاصة بك ، وإذا لم يتم فرز مجموعتك ، فستستمر في استرداد النماذج بترتيب الإدراج. عند تمرير مؤشر سلبي ، سيتم استرداد النموذج من الجزء الخلفي من المجموعة.

push collection.push(model, [options])
Add a model at the end of a collection. Takes the same options as add .

pop collection.pop([options])
Remove and return the last model from a collection. Takes the same options as remove .

unshift collection.unshift(model, [options])
Add a model at the beginning of a collection. Takes the same options as add .

shift collection.shift([options])
Remove and return the first model from a collection. Takes the same options as remove .

slice collection.slice(begin, end)
Return a shallow copy of this collection's models, using the same options as native Array#slice .

length collection.length
Like an array, a Collection maintains a length property, counting the number of models it contains.

comparator collection.comparator
By default there is no comparator for a collection. If you define a comparator, it will be used to maintain the collection in sorted order. This means that as models are added, they are inserted at the correct index in collection.models . A comparator can be defined as a sortBy (pass a function that takes a single argument), as a sort (pass a comparator function that expects two arguments), or as a string indicating the attribute to sort by.

"sortBy" comparator functions take a model and return a numeric or string value by which the model should be ordered relative to others. "sort" comparator functions take two models, and return -1 if the first model should come before the second, 0 if they are of the same rank and 1 if the first model should come after. Note that Backbone depends on the arity of your comparator function to determine between the two styles, so be careful if your comparator function is bound.

Note how even though all of the chapters in this example are added backwards, they come out in the proper order:

var Chapter  = Backbone.Model;
var chapters = new Backbone.Collection;

chapters.comparator = 'page';

chapters.add(new Chapter({page: 9, title: "The End"}));
chapters.add(new Chapter({page: 5, title: "The Middle"}));
chapters.add(new Chapter({page: 1, title: "The Beginning"}));

alert(chapters.pluck('title'));

Collections with a comparator will not automatically re-sort if you later change model attributes, so you may wish to call sort after changing model attributes that would affect the order.

sort collection.sort([options])
Force a collection to re-sort itself. You don't need to call this under normal circumstances, as a collection with a comparator will sort itself whenever a model is added. To disable sorting when adding a model, pass {sort: false} to add . Calling sort triggers a "sort" event on the collection.

pluck collection.pluck(attribute)
Pluck an attribute from each model in the collection. Equivalent to calling map and returning a single attribute from the iterator.

var stooges = new Backbone.Collection([
  {name: "Curly"},
  {name: "Larry"},
  {name: "Moe"}
]);

var names = stooges.pluck("name");

alert(JSON.stringify(names));

where collection.where(attributes)
Return an array of all the models in a collection that match the passed attributes . Useful for simple cases of filter .

var friends = new Backbone.Collection([
  {name: "Athos",      job: "Musketeer"},
  {name: "Porthos",    job: "Musketeer"},
  {name: "Aramis",     job: "Musketeer"},
  {name: "d'Artagnan", job: "Guard"},
]);

var musketeers = friends.where({job: "Musketeer"});

alert(musketeers.length);

findWhere collection.findWhere(attributes)
Just like where , but directly returns only the first model in the collection that matches the passed attributes .

url collection.url or collection.url()
Set the url property (or function) on a collection to reference its location on the server. Models within the collection will use url to construct URLs of their own.

var Notes = Backbone.Collection.extend({
  url: '/notes'
});

// Or, something more sophisticated:

var Notes = Backbone.Collection.extend({
  url: function() {
    return this.document.url() + '/notes';
  }
});

parse collection.parse(response, options)
parse is called by Backbone whenever a collection's models are returned by the server, in fetch . The function is passed the raw response object, and should return the array of model attributes to be add to the collection. The default implementation is a no-op, simply passing through the JSON response. Override this if you need to work with a preexisting API, or better namespace your responses.

var Tweets = Backbone.Collection.extend({
  // The Twitter Search API returns tweets under "results".
  parse: function(response) {
    return response.results;
  }
});

clone collection.clone()
Returns a new instance of the collection with an identical list of models.

fetch collection.fetch([options])
Fetch the default set of models for this collection from the server, setting them on the collection when they arrive. The options hash takes success and error callbacks which will both be passed (collection, response, options) as arguments. When the model data returns from the server, it uses setting to (intelligently) merge the fetched models, unless you pass {reset: true} , in which case the collection will be (efficiently) reset . Delegates to Backbone.sync under the covers for custom persistence strategies and returns a jqXHR . The server handler for fetch requests should return a JSON array of models.

Backbone.sync = function(method, model) {
  alert(method + ": " + model.url);
};

var accounts = new Backbone.Collection;
accounts.url = '/accounts';

accounts.fetch();

The behavior of fetch can be customized by using the available setting options. For example, to fetch a collection, getting an "add" event for every new model, and a "change" event for every changed existing model, without removing anything: collection.fetch({remove: false})

jQuery.ajax options can also be passed directly as fetch options, so to fetch a specific page of a paginated collection: Documents.fetch({data: {page: 3}})

Note that fetch should not be used to populate collections on page load — all models needed at load time should already be bootstrapped in to place. fetch is intended for lazily-loading models for interfaces that are not needed immediately: for example, documents with collections of notes that may be toggled open and closed.

create collection.create(attributes, [options])
Convenience to create a new instance of a model within a collection. Equivalent to instantiating a model with a hash of attributes, saving the model to the server, and adding the model to the set after being successfully created. Returns the new model. If client-side validation failed, the model will be unsaved, with validation errors. In order for this to work, you should set the model property of the collection. The create method can accept either an attributes hash or an existing, unsaved model object.

Creating a model will cause an immediate "add" event to be triggered on the collection, a "request" event as the new model is sent to the server, as well as a "sync" event, once the server has responded with the successful creation of the model. Pass {wait: true} if you'd like to wait for the server before adding the new model to the collection.

var Library = Backbone.Collection.extend({
  model: Book
});

var nypl = new Library;

var othello = nypl.create({
  title: "Othello",
  author: "William Shakespeare"
});

Backbone.Router

Web applications often provide linkable, bookmarkable, shareable URLs for important locations in the app. Until recently, hash fragments ( #page ) were used to provide these permalinks, but with the arrival of the History API, it's now possible to use standard URLs ( /page ). Backbone.Router provides methods for routing client-side pages, and connecting them to actions and events. For browsers which don't yet support the History API, the Router handles graceful fallback and transparent translation to the fragment version of the URL.

During page load, after your application has finished creating all of its routers, be sure to call Backbone.history.start() or Backbone.history.start({pushState: true}) to route the initial URL.

extend Backbone.Router.extend(properties, [classProperties])
Get started by creating a custom router class. Define actions that are triggered when certain URL fragments are matched, and provide a routes hash that pairs routes to actions. Note that you'll want to avoid using a leading slash in your route definitions:

var Workspace = Backbone.Router.extend({

  routes: {
    "help":                 "help",    // #help
    "search/:query":        "search",  // #search/kiwis
    "search/:query/p:page": "search"   // #search/kiwis/p7
  },

  help: function() {
    ...
  },

  search: function(query, page) {
    ...
  }

});

routes router.routes
The routes hash maps URLs with parameters to functions on your router (or just direct function definitions, if you prefer), similar to the View 's events hash . Routes can contain parameter parts, :param , which match a single URL component between slashes; and splat parts *splat , which can match any number of URL components. Part of a route can be made optional by surrounding it in parentheses (/:optional) .

For example, a route of "search/:query/p:page" will match a fragment of #search/obama/p2 , passing "obama" and "2" to the action.

A route of "file/*path" will match #file/folder/file.txt , passing "folder/file.txt" to the action.

A route of "docs/:section(/:subsection)" will match #docs/faq and #docs/faq/installing , passing "faq" to the action in the first case, and passing "faq" and "installing" to the action in the second.

A nested optional route of "docs(/:section)(/:subsection)" will match #docs , #docs/faq , and #docs/faq/installing , passing "faq" to the action in the second case, and passing "faq" and "installing" to the action in the third.

Trailing slashes are treated as part of the URL, and (correctly) treated as a unique route when accessed. docs and docs/ will fire different callbacks. If you can't avoid generating both types of URLs, you can define a "docs(/)" matcher to capture both cases.

When the visitor presses the back button, or enters a URL, and a particular route is matched, the name of the action will be fired as an Events , so that other objects can listen to the router, and be notified. In the following example, visiting #help/uploading will fire a route:help event from the router.

routes: {
  "help/:page":         "help",
  "download/*path":     "download",
  "folder/:name":       "openFolder",
  "folder/:name-:mode": "openFolder"
}
router.on("route:help", function(page) {
  ...
});

constructor / initialize new Router([options])
When creating a new router, you may pass its routes hash directly as an option, if you choose. All options will also be passed to your initialize function, if defined.

route router.route(route, name, [callback])
Manually create a route for the router, The route argument may be a routes or regular expression. Each matching capture from the route or regular expression will be passed as an argument to the callback. The name argument will be triggered as a "route:name" event whenever the route is matched. If the callback argument is omitted router[name] will be used instead. Routes added later may override previously declared routes.

initialize: function(options) {

  // Matches #page/10, passing "10"
  this.route("page/:number", "page", function(number){ ... });

  // Matches /117-a/b/c/open, passing "117-a/b/c" to this.open
  this.route(/^(.*?)\/open$/, "open");

},

open: function(id) { ... }

navigate router.navigate(fragment, [options])
Whenever you reach a point in your application that you'd like to save as a URL, call navigate in order to update the URL. If you also wish to call the route function, set the trigger option to true . To update the URL without creating an entry in the browser's history, set the replace option to true .

openPage: function(pageNumber) {
  this.document.pages.at(pageNumber).open();
  this.navigate("page/" + pageNumber);
}

# Or ...

app.navigate("help/troubleshooting", {trigger: true});

# Or ...

app.navigate("help/troubleshooting", {trigger: true, replace: true});

execute router.execute(callback, args, name)
This method is called internally within the router, whenever a route matches and its corresponding callback is about to be executed. Return false from execute to cancel the current transition. Override it to perform custom parsing or wrapping of your routes, for example, to parse query strings before handing them to your route callback, like so:

var Router = Backbone.Router.extend({
  execute: function(callback, args, name) {
    if (!loggedIn) {
      goToLogin();
      return false;
    }
    args.push(parseQueryString(args.pop()));
    if (callback) callback.apply(this, args);
  }
});

Backbone.history

History serves as a global router (per frame) to handle hashchange events or pushState , match the appropriate route, and trigger callbacks. You shouldn't ever have to create one of these yourself since Backbone.history already contains one.

pushState support exists on a purely opt-in basis in Backbone. Older browsers that don't support pushState will continue to use hash-based URL fragments, and if a hash URL is visited by a pushState -capable browser, it will be transparently upgraded to the true URL. Note that using real URLs requires your web server to be able to correctly render those pages, so back-end changes are required as well. For example, if you have a route of /documents/100 , your web server must be able to serve that page, if the browser visits that URL directly. For full search-engine crawlability, it's best to have the server generate the complete HTML for the page ... but if it's a web application, just rendering the same content you would have for the root URL, and filling in the rest with Backbone Views and JavaScript works fine.

start Backbone.history.start([options])
When all of your Routers have been created, and all of the routes are set up properly, call Backbone.history.start() to begin monitoring hashchange events, and dispatching routes. Subsequent calls to Backbone.history.start() will throw an error, and Backbone.History.started is a boolean value indicating whether it has already been called.

To indicate that you'd like to use HTML5 pushState support in your application, use Backbone.history.start({pushState: true}) . If you'd like to use pushState , but have browsers that don't support it natively use full page refreshes instead, you can add {hashChange: false} to the options.

If your application is not being served from the root url / of your domain, be sure to tell History where the root really is, as an option: Backbone.history.start({pushState: true, root: "/public/search/"})

When called, if a route succeeds with a match for the current URL, Backbone.history.start() returns true . If no defined route matches the current URL, it returns false .

If the server has already rendered the entire page, and you don't want the initial route to trigger when starting History, pass silent: true .

Because hash-based history in Internet Explorer relies on an <iframe> , be sure to call start() only after the DOM is ready.

$(function(){
  new WorkspaceRouter();
  new HelpPaneRouter();
  Backbone.history.start({pushState: true});
});

Backbone.sync

Backbone.sync is the function that Backbone calls every time it attempts to read or save a model to the server. By default, it uses jQuery.ajax to make a RESTful JSON request and returns a jqXHR . You can override it in order to use a different persistence strategy, such as WebSockets, XML transport, or Local Storage.

The method signature of Backbone.sync is sync(method, model, [options])

  • method – the CRUD method ( "create" , "read" , "update" , or "delete" )
  • model – the model to be saved (or collection to be read)
  • options – success and error callbacks, and all other jQuery request options

With the default implementation, when Backbone.sync sends up a request to save a model, its attributes will be passed, serialized as JSON, and sent in the HTTP body with content-type application/json . When returning a JSON response, send down the attributes of the model that have been changed by the server, and need to be updated on the client. When responding to a "read" request from a collection ( fetch ), send down an array of model attribute objects.

Whenever a model or collection begins a sync with the server, a "request" event is emitted. If the request completes successfully you'll get a "sync" event, and an "error" event if not.

The sync function may be overridden globally as Backbone.sync , or at a finer-grained level, by adding a sync function to a Backbone collection or to an individual model.

The default sync handler maps CRUD to REST like so:

  • create → POST /collection
  • read → GET /collection[/id]
  • update → PUT /collection/id
  • patch → PATCH /collection/id
  • delete → DELETE /collection/id

As an example, a Rails 4 handler responding to an "update" call from Backbone might look like this:

def update
  account = Account.find params[:id]
  permitted = params.require(:account).permit(:name, :otherparam)
  account.update_attributes permitted
  render :json => account
end

One more tip for integrating Rails versions prior to 3.1 is to disable the default namespacing for to_json calls on models by setting ActiveRecord::Base.include_root_in_json = false

ajax Backbone.ajax = function(request) { ... };
If you want to use a custom AJAX function, or your endpoint doesn't support the jQuery.ajax API and you need to tweak things, you can do so by setting Backbone.ajax .

emulateHTTP Backbone.emulateHTTP = true
If you want to work with a legacy web server that doesn't support Backbone's default REST/HTTP approach, you may choose to turn on Backbone.emulateHTTP . Setting this option will fake PUT , PATCH and DELETE requests with a HTTP POST , setting the X-HTTP-Method-Override header with the true method. If emulateJSON is also on, the true method will be passed as an additional _method parameter.

Backbone.emulateHTTP = true;

model.save();  // POST to "/collection/id", with "_method=PUT" + header.

emulateJSON Backbone.emulateJSON = true
If you're working with a legacy web server that can't handle requests encoded as application/json , setting Backbone.emulateJSON = true; will cause the JSON to be serialized under a model parameter, and the request to be made with a application/x-www-form-urlencoded MIME type, as if from an HTML form.

Backbone.View

Backbone views are almost more convention than they are code — they don't determine anything about your HTML or CSS for you, and can be used with any JavaScript templating library. The general idea is to organize your interface into logical views, backed by models, each of which can be updated independently when the model changes, without having to redraw the page. Instead of digging into a JSON object, looking up an element in the DOM, and updating the HTML by hand, you can bind your view's render function to the model's "change" event — and now everywhere that model data is displayed in the UI, it is always immediately up to date.

extend Backbone.View.extend(properties, [classProperties])
Get started with views by creating a custom view class. You'll want to override the render function, specify your declarative events , and perhaps the tagName , className , or id of the View's root element.

var DocumentRow = Backbone.View.extend({

  tagName: "li",

  className: "document-row",

  events: {
    "click .icon":          "open",
    "click .button.edit":   "openEditDialog",
    "click .button.delete": "destroy"
  },

  initialize: function() {
    this.listenTo(this.model, "change", this.render);
  },

  render: function() {
    ...
  }

});

Properties like tagName , id , className , el , and events may also be defined as a function, if you want to wait to define them until runtime.

constructor / initialize new View([options])
There are several special options that, if passed, will be attached directly to the view: model , collection , el , id , className , tagName , attributes and events . If the view defines an initialize function, it will be called when the view is first created. If you'd like to create a view that references an element already in the DOM, pass in the element as an option: new View({el: existingElement})

var doc = documents.first();

new DocumentRow({
  model: doc,
  id: "document-row-" + doc.id
});

el view.el
All views have a DOM element at all times (the el property), whether they've already been inserted into the page or not. In this fashion, views can be rendered at any time, and inserted into the DOM all at once, in order to get high-performance UI rendering with as few reflows and repaints as possible.

this.el can be resolved from a DOM selector string or an Element; otherwise it will be created from the view's tagName , className , id and attributes properties. If none are set, this.el is an empty div , which is often just fine. An el reference may also be passed in to the view's constructor.

var ItemView = Backbone.View.extend({
  tagName: 'li'
});

var BodyView = Backbone.View.extend({
  el: 'body'
});

var item = new ItemView();
var body = new BodyView();

alert(item.el + ' ' + body.el);

$el view.$el
A cached jQuery object for the view's element. A handy reference instead of re-wrapping the DOM element all the time.

view.$el.show();

listView.$el.append(itemView.el);

setElement view.setElement(element)
If you'd like to apply a Backbone view to a different DOM element, use setElement , which will also create the cached $el reference and move the view's delegated events from the old element to the new one.

attributes view.attributes
A hash of attributes that will be set as HTML DOM element attributes on the view's el (id, class, data-properties, etc.), or a function that returns such a hash.

$ (jQuery) view.$(selector)
If jQuery is included on the page, each view has a $ function that runs queries scoped within the view's element. If you use this scoped jQuery function, you don't have to use model ids as part of your query to pull out specific elements in a list, and can rely much more on HTML class attributes. It's equivalent to running: view.$el.find(selector)

ui.Chapter = Backbone.View.extend({
  serialize : function() {
    return {
      title: this.$(".title").text(),
      start: this.$(".start-page").text(),
      end:   this.$(".end-page").text()
    };
  }
});

template view.template([data])
While templating for a view isn't a function provided directly by Backbone, it's often a nice convention to define a template function on your views. In this way, when rendering your view, you have convenient access to instance data. For example, using Underscore templates:

var LibraryView = Backbone.View.extend({
  template: _.template(...)
});

render view.render()
The default implementation of render is a no-op. Override this function with your code that renders the view template from model data, and updates this.el with the new HTML. A good convention is to return this at the end of render to enable chained calls.

var Bookmark = Backbone.View.extend({
  template: _.template(...),
  render: function() {
    this.$el.html(this.template(this.model.attributes));
    return this;
  }
});

Backbone is agnostic with respect to your preferred method of HTML templating. Your render function could even munge together an HTML string, or use document.createElement to generate a DOM tree. However, we suggest choosing a nice JavaScript templating library. Mustache.js , Haml-js , and Eco are all fine alternatives. Because Underscore.js is already on the page, _.template is available, and is an excellent choice if you prefer simple interpolated-JavaScript style templates.

Whatever templating strategy you end up with, it's nice if you never have to put strings of HTML in your JavaScript. At DocumentCloud, we use Jammit in order to package up JavaScript templates stored in /app/views as part of our main core.js asset package.

remove view.remove()
Removes a view and its el from the DOM, and calls stopListening to remove any bound events that the view has registered 'd.

events view.events or view.events()
The events hash (or method) can be used to specify a set of DOM events that will be bound to methods on your View through delegateEvents .

Backbone will automatically attach the event listeners at instantiation time, right before invoking initialize .

var ENTER_KEY = 13;
var InputView = Backbone.View.extend({

  tagName: 'input',

  events: {
    "keydown" : "keyAction",
  },

  render: function() { ... },

  keyAction: function(e) {
    if (e.which === ENTER_KEY) {
      this.collection.add({text: this.$el.val()});
    }
  }
});

delegateEvents delegateEvents([events])
Uses jQuery's on function to provide declarative callbacks for DOM events within a view. If an events hash is not passed directly, uses this.events as the source. Events are written in the format {"event selector": "callback"} . The callback may be either the name of a method on the view, or a direct function body. Omitting the selector causes the event to be bound to the view's root element ( this.el ). By default, delegateEvents is called within the View's constructor for you, so if you have a simple events hash, all of your DOM events will always already be connected, and you will never have to call this function yourself.

The events property may also be defined as a function that returns an events hash, to make it easier to programmatically define your events, as well as inherit them from parent views.

Using delegateEvents provides a number of advantages over manually using jQuery to bind events to child elements during render . All attached callbacks are bound to the view before being handed off to jQuery, so when the callbacks are invoked, this continues to refer to the view object. When delegateEvents is run again, perhaps with a different events hash, all callbacks are removed and delegated afresh — useful for views which need to behave differently when in different modes.

A single-event version of delegateEvents is available as delegate . In fact, delegateEvents is simply a multi-event wrapper around delegate . A counterpart to undelegateEvents is available as undelegate .

A view that displays a document in a search result might look something like this:

var DocumentView = Backbone.View.extend({

  events: {
    "dblclick"                : "open",
    "click .icon.doc"         : "select",
    "contextmenu .icon.doc"   : "showMenu",
    "click .show_notes"       : "toggleNotes",
    "click .title .lock"      : "editAccessLevel",
    "mouseover .title .date"  : "showTooltip"
  },

  render: function() {
    this.$el.html(this.template(this.model.attributes));
    return this;
  },

  open: function() {
    window.open(this.model.get("viewer_url"));
  },

  select: function() {
    this.model.set({selected: true});
  },

  ...

});

undelegateEvents undelegateEvents()
Removes all of the view's delegated events. Useful if you want to disable or remove a view from the DOM temporarily.

Utility

Backbone.noConflict var backbone = Backbone.noConflict();
Returns the Backbone object back to its original value. You can use the return value of Backbone.noConflict() to keep a local reference to Backbone. Useful for embedding Backbone on third-party websites, where you don't want to clobber the existing Backbone.

var localBackbone = Backbone.noConflict();
var model = localBackbone.Model.extend(...);

Backbone.$ Backbone.$ = $;
If you have multiple copies of jQuery on the page, or simply want to tell Backbone to use a particular object as its DOM / Ajax library, this is the property for you.

Backbone.$ = require('jquery');

原文