Backbone 中不相关模型的集合?
Collection of unrelated Models in Backbone?
我正在创建一个单页应用程序,让用户可以根据两个条件(技能和位置)过滤数据。此数据将从两个单独的网络服务中填充。
每个服务都有一个使用 REST 样式请求使用数据的模型。
我想在这个视图中同时使用这两个数据位。据我了解,一个集合可以包含一种模型的多个实例,例如"Movie"
var Movies = Backbone.Collection.extend({
model: Movie,
initialize: function() {
console.log("");
console.log("Movie Collection initialize");
console.log(this);
console.log(this.length);
console.log(this.models);
}
});
var movie1 = new Movie({
"title": "Bag It",
"averageUserRating": 4.6,
"yearReleased": 2010,
"mpaaRating": "R"
});
var movie2 = new Movie({
"title": "Lost Boy: The Next Chapter",
"averageUserRating": 4.6,
"yearReleased": 2009,
"mpaaRating": "PG-13"
});
但是我正在尝试实现下面的模式,其中集合有两个模型。这是 Backbone 的反模式吗?应该如何解决?
define([
'underscore',
'backbone',
'models/locationsModel',
'models/skillsModel'
], function (_, Backbone, Location, Skills)
{
'use strict';
var FiltersCollection = Backbone.Collection.extend({
// The filters collection requires these two models that will provide data to the filters view
location: new Location(),
skills: new Skills(),
initialize: function() {
//Do stuff
}
});
return new FiltersCollection();
});
我无法就什么最适合您提出建议,因为我无法根据提供的信息正确地可视化您的数据。但是,如果您观察 Backbone 来源中的集合构造函数:
if (options.model) this.model = options.model;
然后在_prepareModel中:
var model = new this.model(attrs, options);
而且我们知道 "model" 无论如何都是一个函数,一个函数可以 return 你想要的。因此,如果您的两个不同数据源具有一些可以识别它们的属性,您可以这样做:
var SkillModel = Backbone.Model.extend({
sayMyName: function() {
return 'I am a skill model and I am skilled at ' + this.get('name');
}
});
var LocationModel = Backbone.Model.extend({
sayMyName: function() {
return 'I am a location model and I am relaxing in ' + this.get('name');
}
});
function FilterModel(attrs, options) {
if (attrs.type === 'skill') {
return new SkillModel(attrs, options);
} else if (attrs.type === 'location') {
return new LocationModel(attrs, options);
}
}
var FilterCollection = Backbone.Collection.extend({
model: FilterModel
});
var filteredCollection = new FilterCollection([{
type: 'skill',
name: 'carpentry'
}, {
type: 'location',
name: 'India'
}, {
type: 'skill',
name: 'plumbing'
}]);
var outputEl = document.querySelector('#output');
filteredCollection.each(function(model) {
outputEl.innerHTML += '<p>' + model.sayMyName() + '<p>';
});
<script src="http://underscorejs.org/underscore.js"></script>
<script src="http://backbonejs.org/backbone.js"></script>
<div id="output"></div>
我正在创建一个单页应用程序,让用户可以根据两个条件(技能和位置)过滤数据。此数据将从两个单独的网络服务中填充。
每个服务都有一个使用 REST 样式请求使用数据的模型。
我想在这个视图中同时使用这两个数据位。据我了解,一个集合可以包含一种模型的多个实例,例如"Movie"
var Movies = Backbone.Collection.extend({
model: Movie,
initialize: function() {
console.log("");
console.log("Movie Collection initialize");
console.log(this);
console.log(this.length);
console.log(this.models);
}
});
var movie1 = new Movie({
"title": "Bag It",
"averageUserRating": 4.6,
"yearReleased": 2010,
"mpaaRating": "R"
});
var movie2 = new Movie({
"title": "Lost Boy: The Next Chapter",
"averageUserRating": 4.6,
"yearReleased": 2009,
"mpaaRating": "PG-13"
});
但是我正在尝试实现下面的模式,其中集合有两个模型。这是 Backbone 的反模式吗?应该如何解决?
define([
'underscore',
'backbone',
'models/locationsModel',
'models/skillsModel'
], function (_, Backbone, Location, Skills)
{
'use strict';
var FiltersCollection = Backbone.Collection.extend({
// The filters collection requires these two models that will provide data to the filters view
location: new Location(),
skills: new Skills(),
initialize: function() {
//Do stuff
}
});
return new FiltersCollection();
});
我无法就什么最适合您提出建议,因为我无法根据提供的信息正确地可视化您的数据。但是,如果您观察 Backbone 来源中的集合构造函数:
if (options.model) this.model = options.model;
然后在_prepareModel中:
var model = new this.model(attrs, options);
而且我们知道 "model" 无论如何都是一个函数,一个函数可以 return 你想要的。因此,如果您的两个不同数据源具有一些可以识别它们的属性,您可以这样做:
var SkillModel = Backbone.Model.extend({
sayMyName: function() {
return 'I am a skill model and I am skilled at ' + this.get('name');
}
});
var LocationModel = Backbone.Model.extend({
sayMyName: function() {
return 'I am a location model and I am relaxing in ' + this.get('name');
}
});
function FilterModel(attrs, options) {
if (attrs.type === 'skill') {
return new SkillModel(attrs, options);
} else if (attrs.type === 'location') {
return new LocationModel(attrs, options);
}
}
var FilterCollection = Backbone.Collection.extend({
model: FilterModel
});
var filteredCollection = new FilterCollection([{
type: 'skill',
name: 'carpentry'
}, {
type: 'location',
name: 'India'
}, {
type: 'skill',
name: 'plumbing'
}]);
var outputEl = document.querySelector('#output');
filteredCollection.each(function(model) {
outputEl.innerHTML += '<p>' + model.sayMyName() + '<p>';
});
<script src="http://underscorejs.org/underscore.js"></script>
<script src="http://backbonejs.org/backbone.js"></script>
<div id="output"></div>