When we talk about attributes in Backbone, they often sound similar to regular JavaScript properties. After all, both attributes and properties are key-value pairs stored on a Model
object. The difference between the two is that attributes aren't (in a technical sense) actually properties of a Model at all; instead, they are the properties of a property of a Model
. Each Model
class has a property called attributes
, and the attributes themselves are stored as properties of that attributes
property. Take an example of the following code snippet:
var book = new Backbone.Model({pages: 200}); book.renderBlackAndWhite = true; book.renderBlackAndWhite // is a property of book book.attributes.pages; // is an attribute of book book.attributes.currentPage = 1; // is also an attribute of book}
Attributes versus Properties
As shown in the preceding code snippet, Backbone's Models
class can also have regular, nonattribute properties. If you need to store a piece of data in a Model, you can choose between using a property or an attribute. In general, you should use an attribute only when the data is going to be synced to the server or when you want other parts of your code to be able to listen for data changes. If your data doesn't meet these requirements, it's best to store it as a regular JavaScript property instead of as an attribute, because storing such data as an attribute will create more work for you when you save the Model
class.
On a purely conceptual level, any of the core persistent information that a Model
class is designed to hold belongs in its attributes, while any information that is secondary or derived, or which is only designed to last until the user refreshes the page, should be stored as properties.
If you want to pass in attributes when you create a new Model
class, you can simply provide them as the first argument and Backbone will automatically add them. You can also define default attributes, which all new Models
of that class will have, using the defaults property when you extend your Model
class, as shown here:
var Book = Backbone.Model.extend({ defaults: {publisher: 'Packt Publishing'} }); var book = new Book(); book.attributes.publisher; // 'Packt Publishing'
It is important to remember, however, that in JavaScript, objects are passed by reference, which means that any object you provide in defaults
will be shared with, not copied between, instances of your Model
class. In other words, check out the following code snippet:
var Book = Backbone.Model.extend({ defaults: {publisher: {name: 'Packt Publishing'}} }); var book1 = new Book(); book1.attributes.publisher.name // == 'Packt Publishing' var book2 = new Book(); book2.attributes.publisher.name = 'Wack Publishing'; book1.attributes.publisher.name // == 'Wack Publishing'!
Since you probably don't want changes to one Model affecting your other Models, you should avoid setting objects in defaults. If you really need to set an object as a default, you can do so in the Model's initialize
method or by using a more advanced function-based form of defaults, which we'll cover later on in Chapter 7, Fitting Square Pegs in Round Holes – Advanced Backbone Techniques.
While setting default attributes for Models is easy, the same cannot be said about adding default direct properties to a Model when it is first created. The best way to set these properties is to use the Model's initialize
method. For instance, if you want to set a renderBlackAndWhite
property when you create a Book
Model, you can do what is described in the following code snippet:
var Book = Backbone.Model.extend({ initialize: function(attributes, options) { this.renderBlackAndWhite = options.renderBlackAndWhite; } });
The preceding code sets the renderBlackAndWhite
property of each newly created book to the renderBlackAndWhite
option passed in when the book is created.
3.145.152.242