Backbone Model属性可否为Backbone Model普通数组?是否应采用Backbone Collection?
Great question! Let's break this down based on Backbone's design rules and real-world best practices.
从Backbone规范来说:普通数组是允许的
Backbone doesn't enforce strict rules requiring array-like properties to be Backbone Collections. A Model's attributes can be any valid JavaScript value—including plain arrays, objects, even other Backbone Model instances—so long as they can be serialized (the default logic uses JSON.stringify, which works fine for arrays of Models, though note Model instances will serialize to their raw attributes).
So yes, you absolutely can set an attribute like charts to a plain array of Backbone Model instances, and call model.get('charts') to retrieve that array directly.
那为什么大多数时候推荐用Backbone Collection?
While plain arrays are allowed, Collections were built specifically to manage groups of Backbone Models, and they bring a ton of value that plain arrays don't:
- Built-in management methods: Methods like
add(),remove(),get()(fetch by model ID),pluck(), andsort()handle common array manipulation tasks cleanly, no custom logic needed. - Event system: Collections trigger events like
add,remove, andchangewhen their contents update. This makes it trivial to bind views to those changes and keep your UI in sync with data. - Sync capabilities: If you need to fetch or save this group of models to a backend API, Collections have built-in
fetch(),create(), andsave()methods that handle batch operations out of the box. With a plain array, you'd have to implement all that logic yourself. - Data consistency: If you define a
modelproperty on your Collection, it ensures all items added are instances of that Model type, preventing accidental invalid data from being inserted.
When is a plain array acceptable?
There are edge cases where a plain array makes sense:
- The array is static (never modified after initial setup) and doesn't need to trigger any events.
- You don't need any of the Collection's built-in methods, and just need lightweight storage for a small, simple group of Models.
- You're optimizing for minimal overhead (though the difference is negligible for most apps).
Example Code Snippets
Using a plain array
// Define your child Model const ChartModel = Backbone.Model.extend({}); // Parent Model with a plain array attribute const DashboardModel = Backbone.Model.extend({ defaults: { charts: [] } }); // Usage const dashboard = new DashboardModel(); const salesChart = new ChartModel({ id: 1, title: 'Q3 Sales' }); // Manually update the array dashboard.set('charts', [...dashboard.get('charts'), salesChart]); console.log(dashboard.get('charts')); // Logs [ChartModel instance]
Using a Backbone Collection
const ChartModel = Backbone.Model.extend({}); const ChartCollection = Backbone.Collection.extend({ model: ChartModel }); const DashboardModel = Backbone.Model.extend({ defaults: { // Initialize with an empty Collection charts: new ChartCollection() }, // Optional: Ensure any new value for 'charts' is a Collection set: function(key, val, options) { if (key === 'charts' && !(val instanceof ChartCollection)) { val = new ChartCollection(val); } return Backbone.Model.prototype.set.call(this, key, val, options); } }); // Usage const dashboard = new DashboardModel(); const salesChart = new ChartModel({ id: 1, title: 'Q3 Sales' }); // Use Collection's add method dashboard.get('charts').add(salesChart); // Listen for changes to the Collection dashboard.get('charts').on('add', (chart) => { console.log(`Added new chart: ${chart.get('title')}`); });
Final Takeaway
Backbone allows plain arrays as Model attributes, but using a Collection is almost always the better choice for groups of Backbone Models. It makes your code more maintainable, leverages Backbone's built-in functionality, and aligns with the framework's intended design patterns. Only use a plain array if your use case is extremely simple and doesn't require any of the Collection's features.
内容的提问来源于stack exchange,提问作者Mahaveer Agarwal

