Backbone.js 错误:“url”必须指定属性或功能

发布于 2024-12-19 17:21:01 字数 1549 浏览 0 评论 0原文

这实际上是一个答案而不是一个问题。大量使用backbone.js。撞到了一个讨厌的小动物,但在网上没有找到我的具体情况的解释。希望这会节省其他人一些时间。

症状

对从集合中提取的模型调用 f​​etch() 会导致骨干错误:“必须指定“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 的定义放在 People 的定义之后(由于我现在不太有用的排序习惯)代码按字母顺序排列)。

当 Backbone 应我的要求创建 People 实例时,它显然不知道 AppPax.Person,因此它根据 c.fetch() 返回的模型属性创建了自己的 Person 版本 - 里面没有我所有的好东西,包括我的sync()方法。

因此,当我尝试执行 person.fetch() 时,它使用的是它自己的、简约的 Person 定义,而不是我的,并且该定义没有sync() 方法,因此它在 Person 上查找 url 属性/方法,但没有找到它……窒息了。

所以我在 AppPax.People 之前定义了 AppPax.Person 并且一切正常。

This is actually an answer not a question. Using backbone.js heavily. Hit a nasty little critter but did not find an explanation of my particular case online. Hopefully this will save someone else some time.

Symptom

Calling fetch() on a model pulled from a collection results in backbone error: "A 'url' property or function must be specified", even though both collection and model override sync().

Recreation

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();

Resulting backbone error: "A 'url' property or function must be specified"

Misdirected Investigation

So after some debugging and investigation, including looking at the backbone.js code it was clear that Backbone was looking for the url property on the Person model and couldn't find it. However, my Person model overrides sync() and when a model overrides sync() Backbone doesn't demand that the model supply a url property/method.

I also noticed an anomaly: the models in the collection were never instantiated.

All my other stuff based on the exact same pattern had been working fine for a long time.

What to do?

Root Cause

The root cause turned out to be that in my module definition (AppPax) I had put the definition of Person after the definition of People (due to my now-not-so-useful habit of ordering code alphabetically).

When Backbone made an instance of People at my request, it apparently didn't know about AppPax.Person so it created its own version of Person based on the model properties returned by c.fetch() -- without all my good stuff in it, including my sync() method.

So when I tried to do person.fetch() it was using it's own, minimalist Person definition not mine, and that definition had no sync() method, so it looked for a url property/method on Person, didn't find it...choked.

So I defined AppPax.Person before AppPax.People and all worked fine.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文