Spec-Zone.ru › Backbone.js

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)

onobject.on(event, callback, [context])Псевдоним: bind
Связывает функцию обратного вызова с объектом. Обратный вызов будет вызван всякий раз, когда будет сгенерировано событие. Если у вас большое количество разных событий на странице, принято использовать двоеточие для пространств имён: "poll:start", или "change:selection". Строка события также может быть перечнем нескольких событий, разделённых пробелами...

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

Обратные вызовы, связанные со специальным событием "all", будут вызваны при возникновении любого события и получат имя события в качестве первого аргумента. Например, чтобы проксировать все события из одного объекта в другой:

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

Все методы событий Backbone также поддерживают синтаксис карты событий, как альтернативу позиционным аргументам:

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).

offobject.off([event], [callback], [context])Псевдоним: 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 использует для внутренней учёбы.

triggerobject.trigger(event, [*args])
Вызывает обратные вызовы для заданного события или списка событий, разделённых пробелами. Дополнительные аргументы для trigger будут переданы вызовам событий.

onceobject.once(event, callback, [context])
Как и on, но вызывает связанный обратный вызов только один раз, прежде чем удалить его. Удобно, чтобы сказать «в следующий раз, когда произойдёт X, сделать это». Когда передаются несколько событий с использованием синтаксиса, разделённого пробелами, событие будет срабатывать один раз для каждого события, которое вы передали, а не один раз для комбинации всех событий

listenToobject.listenTo(other, event, callback)
Указывает объекту следить за определённым событием другого объекта. Преимущество использования этой формы вместо other.on(event, callback, object), заключается в том, что listenTo позволяет объекту отслеживать события, и их можно удалить все сразу позже. Обратный вызов всегда будет вызываться с объектом в качестве контекста.

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

stopListeningobject.stopListening([other], [event], [callback])
Указывает объекту прекратить прослушивание событий. Либо вызовите stopListening без аргументов, чтобы объект удалил все свои зарегистрированные обратные вызовы... либо будьте более точны, указав ему удалить только события, на которые он подписан на конкретный объект, или конкретное событие, или просто конкретный обратный вызов.

view.stopListening();

view.stopListening(model);

listenToOnceobject.listenToOnce(other, event, callback)
Как и listenTo, но вызывает связанный обратный вызов только один раз, прежде чем удалить его.

Каталог событий
Вот полный список встроенных событий Backbone с аргументами. Вы также можете свободно вызывать свои собственные события в моделях, коллекциях и представлениях, как вам заблагорассудится. Объект Backbone сам смешивает Events, и его можно использовать для отправки любых глобальных событий, необходимых вашему приложению.

  • "add" (модель, коллекция, опции) — когда модель добавляется в коллекцию.
  • "remove" (модель, коллекция, опции) — когда модель удаляется из коллекции.
  • "update" (коллекция, опции) — одно событие, срабатывающее после произвольного количества моделей, добавленных, удалённых или изменённых в коллекции.
  • "reset" (коллекция, опции) — когда содержимое коллекции полностью сброшено.
  • "sort" (коллекция, опции) — когда коллекция была пересортирована.
  • "change" (модель, опции) — когда атрибуты модели были изменены.
  • "changeId" (модель, предыдущийId, опции) — когда идентификатор модели был обновлён.
  • "change:[attribute]" (модель, значение, опции) — когда определённый атрибут был обновлён.
  • "destroy" (модель, коллекция, опции) — когда модель уничтожена.
  • "request" (модель_или_коллекция, xhr, опции) — когда модель или коллекция начали запрос к серверу.
  • "sync" (модель_или_коллекция, ответ, опции) — когда модель или коллекция были успешно синхронизированы с сервером.
  • "error" (модель_или_коллекция, xhr, опции) — когда запрос модели или коллекции к серверу завершился ошибкой.
  • "invalid" (модель, ошибка, опции) — когда валидация модели на клиенте завершилась ошибкой.
  • "route:[имя]" (параметры) — Вызывается маршрутизатором, когда соответствует определённый маршрут.
  • "route" (маршрут, параметры) — Вызывается маршрутизатором, когда любой маршрут был сопоставлен.
  • "route" (маршрутизатор, маршрут, параметры) — Вызывается историей, когда любой маршрут был сопоставлен.
  • "all" — это специальное событие, срабатывающее для любого сгенерированного события, передавая имя события в качестве первого аргумента, за которым следуют все аргументы trigger.

Как правило, при вызове функции, которая генерирует событие (model.set, collection.add, и так далее...), если вы хотите предотвратить срабатывание события, вы можете передать {silent: true} в качестве опции. Обратите внимание, что это редко, возможно, даже никогда, не хорошая идея. Передача конкретного флага в опциях для вашего обратного вызова события для просмотра и выбора игнорирования обычно работает лучше.

Backbone.Model

Модели — сердце любого JavaScript-приложения, содержащие интерактивные данные, а также большую часть логики, связанной с ними: преобразования, валидация, вычисляемые свойства и контроль доступа. Вы расширяете Backbone.Model своими специфичными для области методами, а 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();

extendBackbone.Model.extend(properties, [classProperties])
Чтобы создать свой собственный класс Model, вы расширяете Backbone.Model и предоставляете экземпляр свойства, а также необязательные classProperties, которые будут прикреплены непосредственно к функции конструктора.

extend правильно настраивает цепочку прототипов, поэтому подклассы, созданные с помощью extend, могут быть дальше расширены и подклассифицированы, насколько вы захотите.

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 не предоставляет простого способа вызвать super — функцию с тем же именем, определённую выше по цепочке прототипов. Если вы переопределяете базовую функцию, такую как set, или save, и хотите вызвать реализацию родительского объекта, вам придётся явно вызвать её, примерно так:

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

preinitializenew Model([attributes], [options])
Для использования с моделями как ES-классами. Если вы определяете метод preinitialize, он будет вызван при первом создании модели, прежде чем будет запущена любая логика инициализации для модели.

class Country extends Backbone.Model {
    preinitialize({countryCode}) {
      this.name = COUNTRY_NAMES[countryCode];
    }

    initialize() { ... }
}

конструктор / initializenew Model([attributes], [options])
При создании экземпляра модели вы можете передать начальные значения атрибутов, которые будут установлены в модели. Если вы определите функцию initialize, она будет вызвана при создании модели.

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, прежде чем быть установленными в модели.

getmodel.get(attribute)
Получение текущего значения атрибута из модели. Например: note.get("title")

setmodel.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");

escapemodel.escape(attribute)
Аналогично get, но возвращает HTML-экранированную версию атрибута модели. Если вы вставляете данные из модели в HTML, использование escape для получения атрибутов предотвратит XSS-атаки.

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

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

hasmodel.has(attribute)
Возвращает true, если атрибут имеет значение, отличное от null или undefined.

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

unsetmodel.unset(attribute, [options])
Удаляет атрибут, удаляя его из внутренней хеш-таблицы атрибутов. Срабатывает событие "change" за исключением случаев, когда silent передаётся как опция.

clearmodel.clear([options])
Удаляет все атрибуты из модели, включая атрибут id. Срабатывает событие "change" за исключением случаев, когда silent передаётся как опция.

idmodel.id
Специальное свойство моделей, id — это произвольная строка (целое число или UUID). Если вы зададите id в хэше атрибутов, он будет скопирован в модель как прямое свойство. model.id не следует изменять напрямую, его необходимо изменять только через model.set('id', …). Модели могут быть извлечены по id из коллекций, и id используется для генерации адресов URL моделей по умолчанию.

idAttributemodel.idAttribute
Уникальный идентификатор модели хранится в атрибуте id. Если вы напрямую взаимодействуете с бэкендом (CouchDB, MongoDB), использующим другой уникальный ключ, вы можете установить idAttribute модели, чтобы прозрачно отображать этот ключ в id. Если вы установили idAttribute, вы также можете переопределить cidPrefix.

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

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

cidmodel.cid
Специальное свойство моделей, cid или идентификатор клиента — это уникальный идентификатор, автоматически назначаемый всем моделям при их первом создании. Идентификаторы клиентов полезны, когда модель еще не сохранена на сервере и у нее еще нет окончательного истинного id, но она уже должна быть отображена в пользовательском интерфейсе.

cidPrefixmodel.cidPrefix
Если у вашей модели есть id , который не является целым числом или UUID, существует вероятность столкновения с её cid. Чтобы предотвратить это, вы можете переопределить префикс, с которого начинаются cid.

// If both lengths are 2, refresh the page before running this example.
var clashy = new Backbone.Collection([
  {id: 'c2'},
  {id: 'c1'},
]);
alert('clashy length: ' + clashy.length);

var ClashFree = Backbone.Model.extend({cidPrefix: 'm'});
var clashless = new Backbone.Collection([
  {id: 'c3'},
  {id: 'c2'},
], {model: ClashFree});
alert('clashless length: ' + clashless.length);

attributesmodel.attributes
Свойство attributes — это внутренний хэш, содержащий состояние модели — обычно (но не обязательно) форма JSON-объекта, представляющего данные модели на сервере. Часто это простое представление строки из базы данных, но это также может быть состояние, вычисленное на стороне клиента.

Для обновления свойства attributes используйте метод set, а не непосредственное изменение. Если вам нужно получить и изменить копию атрибутов модели, используйте _.clone(model.attributes) .

Поскольку Events принимает список событий, разделенных пробелами, имена атрибутов не должны содержать пробелы.

changedmodel.changed
Свойство changed — это внутренний хэш, содержащий все атрибуты, которые изменились с момента последнего вызова set. Пожалуйста, не обновляйте changed напрямую, так как его состояние поддерживается внутренне методом set. Копию changed можно получить из changedAttributes.

defaultsmodel.defaults or model.defaults()
Хэш (или функция) defaults можно использовать для задания атрибутов по умолчанию для вашей модели. При создании экземпляра модели все незаданные атрибуты будут установлены в значение по умолчанию.

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

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

Помните, что в JavaScript объекты передаются по ссылке, поэтому если вы включите объект в качестве значения по умолчанию, он будет общим для всех экземпляров. Вместо этого определите defaults как функцию.

toJSONmodel.toJSON([options])
Возвращает неглубокую копию атрибутов модели attributes для сериализации в строку JSON. Это можно использовать для сохранения, сериализации или для дополнения перед отправкой на сервер. Название этого метода немного запутанно, так как он фактически не возвращает строку JSON — но боюсь, что это способ работы API JavaScript для JSON.stringify.

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

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

alert(JSON.stringify(artist));

syncmodel.sync(method, model, [options])
Использует Backbone.sync для сохранения состояния модели на сервере. Может быть переопределен для пользовательского поведения.

fetchmodel.fetch([options])
Объединяет состояние модели с атрибутами, извлеченными с сервера, делегируя вызов Backbone.sync. Возвращает jqXHR. Полезно, если модель еще не заполнена данными или если вам нужно убедиться, что вы имеете последнее состояние сервера. Вызывает событие "change" , если состояние сервера отличается от текущих атрибутов. fetch принимает success и error обратные вызовы в хэше параметров, которые оба передаются (model, response, options) в качестве аргументов.

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

savemodel.save([attributes], [options])
Сохраняет модель в вашей базе данных (или другом слое сохранения), делегируя вызов Backbone.sync. Возвращает jqXHR, если валидация прошла успешно, и false в противном случае. Хэш attributes (как в set) должен содержать атрибуты, которые вы хотите изменить — ключи, которые не указаны, не будут изменены — но на сервер будет отправлено *полное представление* ресурса. Как и в случае с set, вы можете передавать отдельные ключи и значения вместо хэша. Если у модели есть метод validate и валидация завершается ошибкой, модель не будет сохранена. Если модель isNew, сохранение будет "create" (HTTP POST), если модель уже существует на сервере, сохранение будет "update" (HTTP PUT).

Если вместо этого вы хотите отправить только измененные атрибуты на сервер, используйте model.save(attrs, {patch: true}). Вы получите запрос HTTP PATCH на сервер только с переданными атрибутами.

Вызов save с новыми атрибутами вызовет событие "change" немедленно, событие "request" при начале отправки AJAX-запроса на сервер и событие "sync" после того, как сервер подтвердит успешное изменение. Передайте {wait: true} , если вы хотите дождаться ответа сервера перед установкой новых атрибутов в модели.

В следующем примере обратите внимание, как наша переопределенная версия 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"});

save принимает success и error обратные вызовы в хэше параметров, которые будут переданы (model, response, options). Если валидация на стороне сервера завершается ошибкой, верните код HTTP, отличный от 200, вместе с ошибочным ответом в текстовом или JSON формате.

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

destroymodel.destroy([options])
Удаляет модель на сервере, делегируя запрос HTTP DELETE в Backbone.sync. Возвращает объект jqXHR или false , если модель isNew. Принимает success и error обратные вызовы в хэше параметров, которые будут переданы (model, response, options). Вызывает событие "destroy" в модели, которое будет распространяться через любые коллекции, содержащие её, событие "request" при начале отправки AJAX-запроса на сервер и событие "sync" после успешного подтверждения сервером удаления модели. Передайте {wait: true} , если вы хотите дождаться ответа сервера, прежде чем удалять модель из коллекции.

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

Underscore Methods (9)
Backbone делегирует 9 функций для работы с объектами из Underscore.js на Backbone.Model. Они не все здесь документированы, но вы можете ознакомиться с документацией Underscore для получения полной информации…

  • keys
  • values
  • pairs
  • invert
  • pick
  • omit
  • chain
  • isEmpty
user.pick('first_name', 'last_name', 'email');

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

validatemodel.validate(attributes, options)
Этот метод оставлен не определённым, и вам рекомендуется переопределить его с любой пользовательской логикой проверки, которую вы можете выполнить на JavaScript. Если атрибуты валидны, ничего не возвращайте из validate; если они невалидны, верните ошибку по вашему выбору. Это может быть простой текстовой сообщением об ошибке для отображения или полным объектом ошибки, который программно описывает ошибку.

По умолчанию save проверяет validate перед установкой любых атрибутов, но вы также можете сказать set проверять новые атрибуты, передавая {validate: true} в качестве параметра. Метод validate получает атрибуты модели и любые параметры, переданные set или save, если validate возвращает ошибку, 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" события полезны для предоставления сообщений об ошибках общего типа на уровне модели или коллекции.

validationErrormodel.validationError
Значение, возвращенное validate во время последней неудачной проверки.

isValidmodel.isValid(options)
Выполните validate для проверки состояния модели.

Метод validate получает атрибуты модели и любые параметры, переданные в isValid. Если validate возвращает ошибку, вызывается событие "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.set({
  start: 15,
  end:   10
});

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

urlmodel.url()
Возвращает относительный URL, где будет находиться ресурс модели на сервере. Если ваши модели расположены где-то еще, переопределите этот метод с соответствующей логикой. По умолчанию генерирует URL-адреса вида: "[collection.url]/[id]", но вы можете переопределить, указав явный urlRoot, если коллекция модели не должна учитываться.

Делегирует вызов Collection#url для генерации URL-адреса, поэтому убедитесь, что он определен или свойство urlRoot, если все модели этого класса используют один общий корневой URL. Модель с id 101, хранящаяся в Backbone.Collection с url "/documents/7/notes", будет иметь этот URL: "/documents/7/notes/101"

urlRootmodel.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());

parsemodel.parse(response, options)
parse вызывается всякий раз, когда данные модели возвращаются сервером, в fetch и save. Функция получает необработанный response объект и должна вернуть хеш атрибутов, которые будут установлены для модели. По умолчанию реализация ничего не делает, просто передает ответ JSON. Переопределите, если вам нужно работать с существующим API или лучше структурировать свои ответы.

Если вы работаете с бэкендом Rails, у которого есть версия до 3.1, вы заметите, что его реализация to_json по умолчанию включает атрибуты модели в пространстве имён. Чтобы отключить это поведение для бесшовной интеграции с Backbone, установите:

ActiveRecord::Base.include_root_in_json = false

clonemodel.clone()
Возвращает новый экземпляр модели с идентичными атрибутами.

isNewmodel.isNew()
Была ли эта модель уже сохранена на сервере? Если у модели ещё нет id, она считается новой.

hasChangedmodel.hasChanged([attribute])
Изменилась ли модель с момента последнего set? Если передаётся атрибут, возвращает true , если этот конкретный атрибут изменился.

Обратите внимание, что этот метод, и последующие методы, связанные с изменениями, полезны только во время "change" события.

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

changedAttributesmodel.changedAttributes([attributes])
Получить хеш только атрибутов модели, которые изменились с момента последнего set, или false , если изменений нет. Дополнительно, можно передать внешний хеш атрибутов, возвращая атрибуты в этом хеше, которые отличаются от модели. Это можно использовать, чтобы определить, какие части представления следует обновить или какие вызовы необходимо сделать для синхронизации изменений с сервером.

previousmodel.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"});

previousAttributesmodel.previousAttributes()
Возвращает копию предыдущих атрибутов модели. Полезно для получения различий между версиями модели или для возврата к валидному состоянию после возникновения ошибки.

Backbone.Collection

Коллекции — это упорядоченные наборы моделей. Вы можете привязать "change" события, чтобы получать уведомления, когда любая модель в коллекции была изменена, прослушивать "add" и "remove" события, fetch коллекцию с сервера и использовать полный набор методов Underscore.js.

Любое событие, которое срабатывает на модели в коллекции, также будет срабатывать и на самой коллекции для удобства. Это позволяет прослушивать изменения определённых атрибутов в любой модели в коллекции, например: documents.on("change:selected", ...)

extendBackbone.Collection.extend(properties, [classProperties])
Чтобы создать свой собственный класс Collection, расширьте Backbone.Collection, предоставив экземпляры свойств, а также необязательные classProperties, которые будут присоединены непосредственно к функции конструктора коллекции.

modelcollection.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);
    }
  }

});

modelIdcollection.modelId(attrs, idAttribute)
Переопределите этот метод, чтобы вернуть значение, которое коллекция будет использовать для идентификации модели по её атрибутам. Полезно для объединения моделей из нескольких таблиц с различными значениями idAttribute в одну коллекцию.

По умолчанию возвращает значение заданного idAttribute внутри attrs, или, в противном случае, 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);

preinitializenew Backbone.Collection([models], [options])
Для использования с коллекциями как ES классами. Если вы определите метод preinitialize, он будет вызван при первом создании коллекции и до запуска логики инициализации для коллекции.

class Library extends Backbone.Collection {
  preinitialize() {
    this.on("add", function() {
      console.log("Add model event got fired!");
    });
  }
}

constructor / initializenew Backbone.Collection([models], [options])
При создании коллекции вы можете передать начальный массив моделей. Сравнение коллекции может быть включено в качестве параметра. Передача false в качестве параметра сравнения предотвратит сортировку. Если вы определите функцию initialize, она будет вызвана при создании коллекции. Есть несколько параметров, которые, если они предоставлены, будут присоединены непосредственно к коллекции: model и comparator.
Передайте null для models , чтобы создать пустую коллекцию с options.

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

Если {parse: true} передаётся как параметр, атрибуты сначала будут преобразованы методом parse, прежде чем быть установленными в коллекции.

modelscollection.models
Прямой доступ к JavaScript массиву моделей внутри коллекции. Обычно вы захотите использовать get, at, или методы Underscore для доступа к объектам моделей, но иногда требуется прямой доступ к массиву.

toJSONcollection.toJSON([options])
Возвращает массив, содержащий хеши атрибутов каждой модели (через toJSON) в коллекции. Это можно использовать для сериализации и сохранения всей коллекции. Название этого метода немного запутанно, потому что он соответствует API JSON JavaScript.

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

alert(JSON.stringify(collection));

synccollection.sync(method, collection, [options])
Использует Backbone.sync для сохранения состояния коллекции на сервере. Можно переопределить для настраиваемого поведения.

Методы Underscore (46)
Backbone использует Underscore.js для предоставления 46 функций итерации для Backbone.Collection. Они не все документированы здесь, но вы можете ознакомиться с документацией Underscore для получения подробных сведений…

Большинство методов могут принимать объект или строку, чтобы поддерживать предикаты в стиле атрибутов модели или функцию, которая принимает экземпляр модели в качестве аргумента.

  • forEach (each)
  • map (collect)
  • reduce (foldl, inject)
  • reduceRight (foldr)
  • find (detect)
  • findIndex
  • findLastIndex
  • filter (select)
  • reject
  • every (all)
  • some (any)
  • contains (includes)
  • invoke
  • max
  • min
  • sortBy
  • groupBy
  • shuffle
  • toArray
  • size
  • first (head, take)
  • initial
  • rest (tail, drop)
  • last
  • without
  • indexOf
  • lastIndexOf
  • isEmpty
  • chain
  • difference
  • sample
  • partition
  • countBy
  • indexBy
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);

addcollection.add(models, [options])
Добавить модель (или массив моделей) в коллекцию, вызывая событие "add" для каждой модели и событие "update" после этого. Это вариант метода set с теми же параметрами и возвращаемым значением, но он всегда добавляет, и никогда не удаляет. Если вы добавляете модели в коллекцию, которые уже присутствуют в коллекции, они будут проигнорированы, если вы не передадите {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) в коллекцию более одного раза — это бесполезное действие.

removecollection.remove(models, [options])
Удалить модель (или массив моделей) из коллекции и вернуть их. Каждая модель может быть экземпляром Model, id строкой или JS-объектом, любым значением, приемлемым в качестве аргумента id метода collection.get. Срабатывает событие "remove" для каждой модели и одно событие "update" после всех, если {silent: true} не передано. Индекс модели до удаления доступен слушателям как options.index.

resetcollection.reset([models], [options])
Добавление и удаление моделей по одной — хорошо, но иногда вам нужно изменить так много моделей, что лучше обновить коллекцию оптом. Используйте reset, чтобы заменить коллекцию новым списком моделей (или хэшем атрибутов), вызвав одно событие "reset" по завершении и без срабатывания событий добавления или удаления для каких-либо моделей. Возвращает новые модели. Для удобства, в рамках события "reset", список предыдущих моделей доступен как options.previousModels.
Передайте null для models, чтобы очистить вашу коллекцию с помощью options.

Вот пример использования reset для инициализации коллекции во время начальной загрузки страницы в приложении Rails:

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

Вызов collection.reset() без передачи каких-либо моделей в качестве аргументов очистит всю коллекцию.

setcollection.set(models, [options])
Метод set выполняет «умное» обновление коллекции с переданным списком моделей. Если модели в списке ещё нет в коллекции, она будет добавлена; если модель уже есть в коллекции, её атрибуты будут объединены; а если коллекция содержит какие-либо модели, которые не присутствуют в списке, они будут удалены. При этом будут вызваны соответствующие события "add", "remove", и "change", а в конце — одно событие "update". Возвращает изменённые модели в коллекции. Если вы хотите настроить это поведение, вы можете изменить его с помощью опций: {add: false}, {remove: false}, или {merge: false}.

Если свойство model определено, вы также можете передать объекты сырых атрибутов и опции, и они будут оживлены как экземпляры модели с использованием предоставленных опций. Если вы установили comparator, коллекция автоматически отсортируется и вызовет событие "sort", если вы не передадите {sort: false} или не используете опцию {at: index}. Передайте {at: index}, чтобы вставить модель(и) в коллекцию в указанную index.

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.

getcollection.get(id)
Получить модель из коллекции, указав id, cid или передав model.

var book = library.get(110);

atcollection.at(index)
Получить модель из коллекции по индексу. Полезно, если ваша коллекция отсортирована, а если она не отсортирована, at всё равно извлечёт модели в порядке добавления. Если передать отрицательный индекс, он вернёт модель из конца коллекции.

pushcollection.push(model, [options])
Как add, но всегда добавляет модель в конец коллекции и никогда не сортирует.

popcollection.pop([options])
Удалить и вернуть последнюю модель из коллекции. Принимает те же опции, что и remove.

unshiftcollection.unshift(model, [options])
Как add, но всегда добавляет модель в начало коллекции и никогда не сортирует.

shiftcollection.shift([options])
Удалить и вернуть первую модель из коллекции. Принимает те же опции, что и remove.

slicecollection.slice(begin, end)
Вернуть поверхностную копию моделей этой коллекции, используя те же опции, что и у встроенного метода Array#slice.

lengthcollection.length
Как у массива, коллекция поддерживает свойство length, которое подсчитывает количество содержащихся в ней моделей.

comparatorcollection.comparator
По умолчанию для коллекции нет comparator. Если вы определите компаратор, он будет использоваться для сортировки коллекции всякий раз, когда модель добавляется. Компаратор может быть определён как sortBy (передайте функцию, которая принимает один аргумент), как sort (передайте функцию компаратора, которая ожидает два аргумента) или как строка, указывающая атрибут для сортировки.

Функции компаратора «sortBy» принимают модель и возвращают числовое или строковое значение, по которому модель должна быть упорядочена относительно других. Функции компаратора «sort» принимают две модели и возвращают -1, если первая модель должна стоять перед второй, 0, если они имеют одинаковый ранг, и 1, если первая модель должна стоять после второй. Обратите внимание, что Backbone полагается на арность вашей функции компаратора, чтобы определить между двумя стилями, поэтому будьте осторожны, если ваша функция компаратора связана.

Обратите внимание, что, хотя все главы в этом примере добавлены в обратном порядке, они выходят в правильном порядке:

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'));

Коллекции с компаратором не будут автоматически пересортированы, если вы позже измените атрибуты моделей, поэтому вы можете вызвать sort после изменения атрибутов модели, которые повлияют на порядок.

sortcollection.sort([options])
Вынудительно пересортировать коллекцию. Обратите внимание, что коллекция с comparator будет сортироваться автоматически всякий раз, когда добавляется модель. Чтобы отключить сортировку при добавлении модели, передайте {sort: false} в add. Вызов sort вызывает событие "sort" в коллекции.

pluckcollection.pluck(attribute)
Извлечь атрибут из каждой модели в коллекции. Эквивалентно вызову map и возвращению единственного атрибута от итератора.

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

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

alert(JSON.stringify(names));

wherecollection.where(attributes)
Вернуть массив всех моделей в коллекции, которые соответствуют переданным attributes. Полезно для простых случаев 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);

findWherecollection.findWhere(attributes)
Как и where, но возвращает только первую модель в коллекции, которая соответствует переданным attributes. Если ни одна модель не соответствует, возвращает undefined.

urlcollection.url or collection.url()
Установите свойство url (или функцию) в коллекции, чтобы сослаться на её местоположение на сервере. Модели в коллекции будут использовать url для построения собственных URL-адресов.

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

// Or, something more sophisticated:

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

parsecollection.parse(response, options)
parse вызывается Backbone всякий раз, когда модели коллекции возвращаются сервером в методе fetch. Функция получает объект response в сыром виде и должна вернуть массив атрибутов моделей, которые нужно добавить в коллекцию. По умолчанию — пустая функция, которая просто пропускает JSON-ответ. Переопределите её, если вам нужно работать с существующим API или лучше структурировать ваши ответы.

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

clonecollection.clone()
Возвращает новый экземпляр коллекции с идентичным списком моделей.

fetchcollection.fetch([options])
Загрузить стандартный набор моделей для этой коллекции с сервера, устанавливая их в коллекции по их получению. Хэш options принимает success и error обратные вызовы, которые оба получат (collection, response, options) в качестве аргументов. При возврате данных модели с сервера используется set для (умного) слияния загруженных моделей, если вы не передали {reset: true}, в этом случае коллекция будет (эффективно) resetа. Делегирует в Backbone.sync для пользовательских стратегий сохранения и возвращает jqXHR. Обработчик запроса fetch на сервере должен возвращать JSON-массив моделей.

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

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

accounts.fetch();

Поведение fetch можно настроить, используя доступные опции set. Например, чтобы загрузить коллекцию, получив событие "add" для каждой новой модели и событие "change" для каждой изменённой существующей модели, не удаляя ничего: collection.fetch({remove: false})

Опции jQuery.ajax также могут быть переданы напрямую как опции fetch, поэтому для загрузки определённой страницы постраничной коллекции: Documents.fetch({data: {page: 3}})

Обратите внимание, что fetch не следует использовать для заполнения коллекций при загрузке страницы — все необходимые модели должны быть инициализированы заранее. fetch предназначен для ленивой загрузки моделей для интерфейсов, которые не нужны немедленно: например, документы с коллекциями заметок, которые могут быть открыты и закрыты.

createcollection.create(attributes, [options])
Удобный способ создать новый экземпляр модели в коллекции. Эквивалентно созданию модели с хэш-атрибутами, сохранению модели на сервере и добавлению модели в набор после успешного создания. Возвращает новую модель. Если клиентская проверка данных завершилась неудачно, модель не будет сохранена, с ошибками проверки.

Для работы этого метода, вы должны установить свойство model коллекции. Метод create может принимать либо хэш атрибутов и опций, которые будут переданы во время создания модели, или существующий, несохранённый объект модели.

Создание модели вызовет непосредственное событие "add" в коллекции, событие "request" по мере отправки новой модели на сервер, а также событие "sync", как только сервер ответит успешным созданием модели. Передайте {wait: true}, если вы хотите дождаться ответа сервера, прежде чем добавлять новую модель в коллекцию.

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

var nypl = new Library;

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

mixinBackbone.Collection.mixin(properties)
mixin предоставляет способ расширения базового Backbone.Collection и любых коллекций, которые его расширяют. Это можно использовать для добавления общих методов (например, дополнительных методов Underscore Methods).

Backbone.Collection.mixin({
  sum: function(models, iteratee) {
    return _.reduce(models, function(s, m) {
      return s + iteratee(m);
    }, 0);
  }
});

var cart = new Backbone.Collection([
  {price: 16, name: 'monopoly'},
  {price: 5, name: 'deck of cards'},
  {price: 20, name: 'chess'}
]);

var cost = cart.sum('price');

Backbone.Router

Веб-приложения часто предоставляют ссылки, которые можно занести в закладки, делиться ими и представлять важные места в приложении. До недавнего времени для обеспечения этих постоянных ссылок использовались фрагменты хэша (#page), но с появлением API истории теперь можно использовать стандартные URL-адреса (/page). Backbone.Router предоставляет методы для маршрутизации клиентских страниц и их связи с действиями и событиями. Для браузеров, которые пока не поддерживают API истории, маршрутизатор обрабатывает плавный откат и прозрачное преобразование в фрагментную версию URL-адреса.

Во время загрузки страницы, после того как ваше приложение закончит создание всех маршрутизаторов, обязательно вызовите Backbone.history.start() или Backbone.history.start({pushState: true}), чтобы маршрутизировать начальный URL-адрес.

extendBackbone.Router.extend(properties, [classProperties])
Начните с создания пользовательского класса маршрутизатора. Определите функции действий, которые срабатывают при сопоставлении определённых фрагментов URL-адресов, и предоставьте хэш маршрутов, который сопоставляет маршруты с действиями. Обратите внимание, что вы должны избегать использования ведущего слэша в определениях маршрутов:

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) {
    ...
  }

});

routesrouter.routes
Хэш маршрутов сопоставляет URL-адреса с параметрами с функциями вашего маршрутизатора (или просто с прямыми определениями функций, если вы предпочитаете), аналогично хэшу событий View's events hash. Маршруты могут содержать части параметров, :param, которые соответствуют одному компоненту URL-адреса между слэшами; и части со звездочкой *splat, которые могут соответствовать любому количеству компонентов URL-адреса. Часть маршрута может быть сделана необязательной, поместив её в скобки (/:optional).

Например, маршрут "search/:query/p:page" будет соответствовать фрагменту #search/obama/p2, передавая "obama" и "2" в действие в качестве позиционных аргументов.

Маршрут "file/*path" будет соответствовать #file/folder/file.txt, передавая "folder/file.txt" в действие.

Маршрут "docs/:section(/:subsection)" будет соответствовать #docs/faq и #docs/faq/installing, передавая "faq" в действие в первом случае и передавая "faq" и "installing" в действие во втором.

Вложенный необязательный маршрут "docs(/:section)(/:subsection)" будет соответствовать #docs, #docs/faq, и #docs/faq/installing, передавая "faq" в действие во втором случае и передавая "faq" и "installing" в действие в третьем.

Конечные слэши обрабатываются как часть URL-адреса и (правильно) обрабатываются как уникальный маршрут при доступе. docs и docs/ будут вызывать разные обратные вызовы. Если вы не можете избежать генерации обоих типов URL-адресов, вы можете определить "docs(/)" для захвата обоих случаев.

Когда посетитель нажимает кнопку "Назад" или вводит URL-адрес, и определённый маршрут совпадает, имя действия будет вызвано как событие событие, чтобы другие объекты могли прослушивать маршрутизатор и получать уведомления. В следующем примере посещение #help/uploading будет вызывать событие route:help от маршрутизатора.

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

preinitializenew Backbone.Router([options])
Для использования с маршрутизаторами в качестве классов ES. Если вы определите метод preinitialize, он будет вызываться при первом создании маршрутизатора и до запуска какой-либо логики инициализации для маршрутизатора.

class Router extends Backbone.Router {
  preinitialize() {
    // Override execute method
    this.execute = function(callback, args, name) {
      if (!loggedIn) {
        goToLogin();
        return false;
      }
      args.push(parseQueryString(args.pop()));
      if (callback) callback.apply(this, args);
    }
  }
}

constructor / initializenew Router([options])
При создании нового маршрутизатора вы можете передать хэш его маршрутов напрямую в качестве параметра, если хотите. Все options также будут переданы вашей функции initialize, если она определена.

routerouter.route(route, name, [callback])
Ручное создание маршрута для маршрутизатора. Аргумент route может быть строкой маршрутизации или регулярным выражением. Каждый захваченный параметр из маршрута или регулярного выражения будет передан в качестве аргумента обратной функции. Аргумент name будет вызываться как событие "route:name" всякий раз, когда маршрут совпадает. Если аргумент callback опущен, router[name] будет использован вместо него. Маршруты, добавленные позже, могут переопределять ранее объявленные маршруты.

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) { ... }

navigaterouter.navigate(fragment, [options])
Всякий раз, когда вы достигаете точки в приложении, которую вы хотите сохранить в виде URL-адреса, вызовите navigate, чтобы обновить URL-адрес. Если вы также хотите вызвать функцию маршрута, установите параметр trigger в true. Чтобы обновить URL-адрес, не создавая запись в истории браузера, установите параметр replace в 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});

executerouter.execute(callback, args, name)
Этот метод вызывается внутри маршрутизатора, всякий раз, когда маршрут совпадает, и его соответствующий callback собирается быть выполнен. Верните false из execute, чтобы отменить текущий переход. Переопределите его, чтобы выполнить пользовательское разбиение или обёртку маршрутов, например, чтобы разобрать строки запросов перед передачей их обратной функции маршрута, как показано ниже:

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 служит глобальным маршрутизатором (на фрейм) для обработки hashchange событий или pushState, сопоставления соответствующего маршрута и запуска обратных вызовов. Вам не нужно создавать такой самостоятельно, так как Backbone.history уже содержит один.

Поддержка pushState существует в Backbone на чисто опционной основе. Более старые браузеры, которые не поддерживают pushState, будут по-прежнему использовать фрагменты URL-адресов на основе хэша, и если URL-адрес хэша посещается браузером, способным к pushState, он будет прозрачно обновлён до истинного URL-адреса. Обратите внимание, что использование реальных URL-адресов требует, чтобы ваш веб-сервер мог корректно отображать эти страницы, поэтому необходимы изменения на стороне сервера. Например, если у вас есть маршрут /documents/100, ваш веб-сервер должен уметь обслуживать эту страницу, если браузер посещает этот URL-адрес напрямую. Для полной индексации поисковыми системами лучше всего, чтобы сервер генерировал полную HTML-страницу... но если это веб-приложение, то просто отображение того же контента, что и для корневого URL-адреса, и заполнение остальной части с помощью Backbone Views и JavaScript работает нормально.

startBackbone.history.start([options])
Когда все ваши маршрутизаторы будут созданы и все маршруты будут правильно настроены, вызовите Backbone.history.start() для начала мониторинга hashchange событий и отправки маршрутов. Последующие вызовы Backbone.history.start() приведут к ошибке, и Backbone.History.started является булевым значением, указывающим, был ли он уже вызван.

Чтобы указать, что вы хотите использовать поддержку HTML5 pushState в своём приложении, используйте Backbone.history.start({pushState: true}). Если вы хотите использовать pushState, но браузеры, которые не поддерживают его изначально, используют вместо этого полные обновления страницы, вы можете добавить {hashChange: false} к параметрам.

Если ваше приложение не обслуживается с корневого URL-адреса / вашего домена, убедитесь, что вы сказали History, где корень на самом деле находится, как опцию: Backbone.history.start({pushState: true, root: "/public/search/"}).

Значение, предоставленное для root, будет нормализовано, чтобы включать ведущий и конечный слэш. При переходе по маршруту поведение по умолчанию заключается в исключении конечного слэша из URL-адреса (например, /public/search?query=...). Если вы предпочитаете включать конечный слэш (например, /public/search/?query=...), используйте Backbone.history.start({trailingSlash: true}). URL-адреса всегда будут содержать ведущий слэш. Когда root — /, URL-адреса будут выглядеть как /?query=... независимо от значения trailingSlash.

При вызове, если маршрут успешно совпадает с текущим URL-адресом, Backbone.history.start() возвращает true. Если ни один определённый маршрут не совпадает с текущим URL-адресом, он возвращает false.

Если сервер уже отобразил всю страницу и вы не хотите, чтобы начальный маршрут срабатывал при запуске History, передайте silent: true.

Поскольку хэш-базовая история в Internet Explorer полагается на <iframe>, убедитесь, что вы вызываете start() только после того, как DOM будет готов.

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

Backbone.sync

Backbone.sync — это функция, которую Backbone вызывает всякий раз, когда пытается прочитать или сохранить модель на сервере. По умолчанию она использует jQuery.ajax для отправки RESTful JSON-запроса и возвращает jqXHR. Вы можете переопределить её, чтобы использовать другую стратегию сохранения, такую как WebSockets, XML-транспорт или Local Storage.

Подпись метода Backbone.sync — sync(method, model, [options])

  • method — метод CRUD ("create", "read", "update", или "delete")
  • model — модель, которая должна быть сохранена (или коллекция, которая должна быть прочитана)
  • options — обратные вызовы success и error, а также все остальные параметры запроса jQuery

При использовании реализации по умолчанию, когда Backbone.sync отправляет запрос на сохранение модели, её атрибуты будут переданы, сериализованы как JSON и отправлены в теле HTTP с типом контента application/json. При возвращении JSON-ответа отправляются атрибуты модели, которые были изменены сервером и должны быть обновлены на клиенте. При ответе на запрос "read" от коллекции (Collection#fetch), отправляется массив объектов атрибутов модели.

Всякий раз, когда модель или коллекция начинает sync с сервером, генерируется событие "request". Если запрос завершается успешно, вы получите событие "sync", и событие "error", если нет.

Функция sync может быть переопределена глобально как Backbone.sync, или на более детальном уровне, добавив функцию sync в коллекцию Backbone или в отдельную модель.

Обработчик sync по умолчанию отображает CRUD на REST следующим образом:

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

В качестве примера, обработчик Rails 4, отвечающий на вызов "update" от Backbone, может выглядеть так:

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

Ещё один совет для интеграции версий Rails до 3.1 — отключить стандартное именование пространства имён для вызовов to_json на моделях, установив ActiveRecord::Base.include_root_in_json = false

ajaxBackbone.ajax = function(request) { ... };
Если вы хотите использовать пользовательскую функцию AJAX или ваш конечный пункт не поддерживает API jQuery.ajax, и вам нужно что-то подправить, вы можете сделать это, установив Backbone.ajax.

emulateHTTPBackbone.emulateHTTP = true
Если вам нужно работать с устаревшим веб-сервером, который не поддерживает стандартный подход Backbone REST/HTTP, вы можете включить Backbone.emulateHTTP. Установка этого параметра позволит имитировать запросы PUT, PATCH и DELETE с помощью HTTP POST, установив заголовок X-HTTP-Method-Override со значением истинного метода. Если emulateJSON также включён, истинный метод будет передан в качестве дополнительного параметра _method.

Backbone.emulateHTTP = true;

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

emulateJSONBackbone.emulateJSON = true
Если вы работаете с устаревшим веб-сервером, который не может обрабатывать запросы, закодированные как application/json, установка Backbone.emulateJSON = true; заставит JSON быть сериализованным под параметром model, и запрос будет выполнен с типом MIME application/x-www-form-urlencoded, как будто из HTML-формы.

Backbone.View

Виды Backbone — это скорее соглашение, чем код — они не определяют ничего в вашем HTML или CSS, и могут использоваться с любой JavaScript-библиотекой шаблонизации. Основная идея заключается в организации вашего интерфейса в логические представления, поддерживаемые моделями, каждое из которых может быть обновлено независимо при изменении модели, не перерисовывая всю страницу. Вместо того, чтобы копаться в объекте JSON, искать элемент в DOM и вручную обновлять HTML, вы можете привязать функцию render своего представления к событию "change" модели — и теперь все данные модели, отображаемые в пользовательском интерфейсе, всегда будут актуальными.

extendBackbone.View.extend(properties, [classProperties])
Начните с представлений, создав пользовательский класс представления. Вам нужно будет переопределить функцию render, указать ваши декларативные события, и, возможно, tagName, className, или id корневого элемента представления.

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() {
    ...
  }

});

Свойства, такие как tagName, id, className, el, и events, также могут быть определены как функции, если вы хотите определить их во время выполнения.

preinitializenew View([options])
Для использования с представлениями как классами ES. Если вы определите метод preinitialize, он будет вызван при первом создании представления, перед запуском любой логики инициализации.

class Document extends Backbone.View {
  preinitialize({autoRender}) {
    this.autoRender = autoRender;
  }

  initialize() {
    if (this.autoRender) {
      this.listenTo(this.model, "change", this.render);
    }
  }
}

конструктор / initializenew View([options])
Есть несколько специальных опций, которые, если переданы, будут прикреплены непосредственно к представлению: model, collection, el, id, className, tagName, attributes и events. Если представление определяет функцию initialize, она будет вызвана при первом создании представления. Если вы хотите создать представление, ссылающееся на элемент, уже находящийся в DOM, передайте элемент как опцию: new View({el: existingElement})

var doc = documents.first();

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

elview.el
Все представления имеют элемент DOM в любое время (свойство el), независимо от того, были ли они уже вставлены на страницу или нет. Таким образом, представления могут быть рендерированы в любое время и вставлены в DOM сразу, чтобы получить высокопроизводительное рендеринг пользовательского интерфейса с минимальным количеством перестроек и перерисовок.

this.el может быть получено из строки селектора DOM или элемента; в противном случае оно будет создано из свойств представления tagName, className, id и attributes. Если ни одно из них не установлено, this.el — это пустой div, что часто вполне подходит. Ссылка на el также может быть передана в конструктор представления.

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);

$elview.$el
Кэшированный объект jQuery для элемента представления. Удобная ссылка вместо повторной обёртки элемента DOM каждый раз.

view.$el.show();

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

setElementview.setElement(element)
Если вы хотите применить представление Backbone к другому элементу DOM, используйте setElement, который также создаст кэшированную ссылку $el и перенесёт делегированные события представления со старого элемента на новый.

attributesview.attributes
Хэш атрибутов, которые будут установлены как атрибуты элемента HTML DOM в элементе представления (id, class, атрибуты data-свойств и т. д.) или функция, возвращающая такой хэш.

$ (jQuery)view.$(selector)
Если на странице включена jQuery, каждое представление имеет функцию $, которая выполняет запросы, ограниченные элементом представления. Если вы используете эту функцию jQuery, вам не нужно использовать идентификаторы моделей в качестве части вашего запроса, чтобы извлечь определённые элементы в списке, и вы можете больше полагаться на атрибуты класса HTML. Это эквивалентно выполнению: 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()
    };
  }
});

шаблонview.template([data])
Хотя шаблон для представления не является функцией, непосредственно предоставленной Backbone, часто удобно определить функцию template в ваших представлениях. Таким образом, при рендеринге вашего представления у вас будет удобный доступ к данным экземпляра. Например, с использованием шаблонов Underscore:

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

renderview.render()
По умолчанию реализация render — это пустая операция. Переопределите эту функцию своим кодом, который рендерит шаблон представления из данных модели и обновляет this.el новым HTML. Хорошим соглашением является вызов return this в конце render, чтобы включить цепочечные вызовы.

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

Backbone не зависит от вашего предпочтительного метода шаблонизации HTML. Ваша функция render может даже склеить строку HTML или использовать document.createElement для генерации дерева DOM. Тем не менее, мы рекомендуем выбрать хорошую JavaScript-библиотеку шаблонизации. Mustache.js, Haml-js и Eco — все хорошие альтернативы. Поскольку Underscore.js уже на странице, _.template доступен и является отличным выбором, если вы предпочитаете простые шаблоны с интерполированным JavaScript.

Какой бы стратегией шаблонизации вы ни выбрали, неплохо бы никогда не вставлять строки HTML в свой JavaScript. В DocumentCloud мы используем Jammit, чтобы упаковать JavaScript-шаблоны, хранящиеся в /app/views, в качестве части нашего основного core.js пакета ресурсов.

removeview.remove()
Удаляет представление и его el из DOM и вызывает stopListening, чтобы удалить любые привязанные события, к которым представление listenTo'd.

событияview.events or view.events()
Хэш событий (или метод) можно использовать для указания набора событий DOM, которые будут привязаны к методам вашего представления через delegateEvents.

Backbone автоматически подключит обработчики событий во время инициализации, непосредственно перед вызовом 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()});
    }
  }
});

delegateEventsdelegateEvents([events])
Использует функцию jQuery on для предоставления декларативных обратных вызовов для событий DOM внутри представления. Если хэш событий не передан непосредственно, используется this.events в качестве источника. События записываются в формате {"event selector": "callback"}. Обратный вызов может быть либо именем метода представления, либо непосредственным телом функции. Пропуск selector приводит к привязке события к корневому элементу представления (this.el). По умолчанию delegateEvents вызывается внутри конструктора представления, поэтому если у вас простой хэш events, все ваши события DOM всегда будут подключены, и вам никогда не придётся вызывать эту функцию самостоятельно.

Свойство events также может быть определено как функция, возвращающая хэш событий, чтобы упростить программирование определения ваших событий, а также их наследование от родительских представлений.

Использование delegateEvents предоставляет ряд преимуществ по сравнению с ручным использованием jQuery для привязки событий к дочерним элементам во время render. Все прикреплённые обратные вызовы привязываются к представлению перед передачей в jQuery, поэтому при вызове обратных вызовов this по-прежнему ссылается на объект представления. Когда delegateEvents выполняется снова, возможно, с другим хэшем events, все обратные вызовы удаляются и делегируются заново — полезно для представлений, которые должны вести себя по-разному в разных режимах.

Однособытийная версия delegateEvents доступна как delegate. Фактически, delegateEvents — это просто многособытийная оболочка вокруг delegate. Противоположность undelegateEvents доступна как undelegate.

Представление, отображающее документ в результате поиска, может выглядеть примерно так:

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});
  },

  ...

});

undelegateEventsundelegateEvents()
Удаляет все делегированные события представления. Полезно, если вы хотите временно отключить или удалить представление из DOM.

Служебные функции

Backbone.noConflictvar backbone = Backbone.noConflict();
Возвращает объект Backbone к его первоначальному значению. Вы можете использовать возвращаемое значение Backbone.noConflict() для сохранения локальной ссылки на Backbone. Полезно для встраивания Backbone на сторонних веб-сайтах, где вы не хотите перезаписывать существующий Backbone.

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

Backbone.$Backbone.$ = $;
Если на странице есть несколько копий jQuery, или вы просто хотите сказать Backbone использовать определённый объект в качестве своей библиотеки DOM/Ajax, это нужное вам свойство.

Backbone.$ = require('jquery');

© 2010–2023 Jeremy Ashkenas, DocumentCloud
Licensed under the MIT License.
https://backbonejs.org/

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API