我正在发现 BackBone JS(顺便说一句,它看起来非常棒),并且在验证模型和过滤集合方面遇到了一些问题。
首先,这是我的代码:
$(document).ready(function() {
window.Movie = Backbone.Model.extend({
defaults: {
id: "?",
title: "Default movie title",
year: "Unknown",
seen: false
},
initialize: function Movie() {
this.bind("error", function(model, error) {
console.log("An error occured --> "+error);
});
},
_validate: function(attributes) {
console.log("Validation function called");
if(attributes.title == '') {
return "Title cannot be empty";
}
if(attributes.year > new Date().getFullYear()) {
return "Woops... looks like this movie is a time traveler"
}
if(typeof attributes.seen != 'boolean') {
return "Attribute 'seen' must be a boolean";
}
}
});
m1 = new Movie({year: 2012, title: 'My movie', id: 1});
m1.set({title: '', year: 2042});
});
此代码包含在 index.html 页面中,该页面之前加载了 jQuery、UnderscoreJS 和 BackboneJS。
尝试设置空标题时,此代码应在控制台中显示错误,但即使使用正确的attributes
参数调用 _validate 函数,它也不会显示错误。请注意,起初我只是简单地命名了该函数validate
(没有下划线),就像我在教程中阅读的那样,但在创建或修改电影时根本没有调用它。
或者,我有一个电影对象的集合,现在几乎是空的:
window.Movies = Backbone.Collection.extend({
model: Movie,
initialize: function Movies() {}
});
m1 = new Movie({year: 1998, title: "Worldcup", id: 1});
m2 = new Movie({year: 1995, title: "1995 movie", id: 2});
m3 = new Movie({year: 2012, title: "2012", id: 3});
m4 = new Movie({year: 2008, title: "2008 movie", id: 4});
movies = new Movies();
movies.add([m1, m2, m3, m4]);
console.log("Displaying movies released after 2000 :");
var recent = movies.filter(function(movie) {
return movie.get('year') > 2000;
});
for(var i in recent) {
console.log(recent[i].get('title'));
}
filter 函数不返回任何结果(应该有 2 个)。所以我尝试console.log(movie)
在这个函数中,显然传递给回调的电影总是未定义的。所以我在谷歌上搜索,我发现了许多不同的语法,其中许多涉及在集合中创建过滤器函数:
/* Returns a 'wrapped object' containing none of the movies it should */
getRecent: function(year) {
return _(this.filter(function(movie) {
return movie.get('year') > year;
}));
}
/* Does not work either : console.log on result gives http://bit.ly/ZvlkNi */
getRecent: function(year) {
var filtered = this.filter(function(movie) {
return movie.get('year') > year;
});
return new Movies(filtered);
}
/* Returns an empty array */
getRecent: function(year) {
return this.filter(function(movie) {
return movie.get('year') > year;
});
}
我有点迷失了,主要是因为似乎有很多不同的方法可以做同样的事情,而且它们似乎都不适用于我的情况。
非常感谢您的帮助!克里斯托夫。