这实际上是一个答案而不是一个问题。大量使用backbone.js。遇到一个讨厌的小动物,但没有在网上找到我的特定案例的解释。希望这能节省一些时间。
症状
对从集合中提取的模型调用fetch()会导致主干错误:“必须指定''url'属性或函数”,即使集合和模型都覆盖sync()。
娱乐
AppPax.People = Backbone.Collection.extend({
...
model: AppPax.Person,
...
});
...
AppPax.Person = AppPax.Model.extend({
...
sync: function(method, model, options) {
var response;
switch (method) {
case "read": response = AppPax.getPerson(this.get("party_id"));
break;
...
},
...
});
var c = new AppPax.People();
c.fetch();
var person = c.find(function(person){
return(person.get("party_id") == "5");
});
// everything seemingly successful up to here (but not really)
person.fetch();
产生的主干错误:“必须指定'url'属性或函数”
误导调查
因此经过一些调试和调查,包括查看backbone.js代码后,很明显Backbone正在寻找Person模型上的url属性而无法找到它。但是,我的Person模型会覆盖sync(),当模型覆盖sync()时,Backbone不要求模型提供url属性/方法。
我也注意到一个异常现象:集合中的模型从未实例化过。
基于相同模式的所有其他东西在很长一段时间内都运行良好。
怎么办?
根本原因
根本原因结果是在我的模块定义(AppPax)中我在Person的定义之后放了Person的定义(由于我现在不太习惯按字母顺序排序代码)。
当Backbone根据我的请求创建了People的实例时,它显然不知道AppPax.Person所以它根据c.fetch()返回的模型属性创建了自己的Person版本 - 没有我的好处其中的东西,包括我的sync()方法。
所以,当我尝试做person.fetch()时,它使用了它自己的,极简主义的Person定义而不是我的,并且该定义没有sync()方法,因此它在Person上找到了url属性/方法,没有'找到它......窒息。
所以我在AppPax.People之前定义了AppPax.Person并且一切正常。