【问题标题】:Error: A "url" property or function must be specified, except url is specified错误:必须指定“url”属性或函数,但指定了 url
【发布时间】:2014-10-16 09:16:52
【问题描述】:

我有一个对话模型和一个显示该模型的视图。从服务器获取该模型没有任何问题(此时 url 属性工作正常),并呈现视图。 但是,当我尝试在视图的函数中销毁模型时,我收到错误“必须指定“url”属性或函数',即使我在销毁调用之前显示该 url,它正是网址应该是。

这是模型的代码:

MessageManager.models.Conversation = Backbone.Model.extend({
    defaults: {
        uid: '',
        title: '',
        messages: [],
        users: [],
        dateUpdated: null,
        isNew: true,
        message: ''
    },
    url: function(){
        var url = '/api/conversations';
        if(this.get('uid').length > 0) url += '/'+this.get('uid');
        return url;
    }
});

还有观点:

MessageManager.views.ConversationFull = Marionette.CompositeView.extend({
    template: this.template(MessageManager.templates.ConversationFull),
    childView: MessageManager.views.MessageListItem,
    childViewContainer: '#message-container',
    events: {
        'click a#btn-delete-conversation': 'deleteConversation'
    },
    deleteConversation: function(e){
        e.preventDefault();
        var self = this;
        console.log(self.model.url()); //This returns a correct url

        self.model.destroy({//This fires the error
            error: function(model, result, xhr){
                console.log(result.responseText);
            },
            success: function(model, response, options){
                MessageManager.conversations.sync();
                AMMain.router.pNavigate('welcome/');
            }
        });
    }
});

谁能提供一些关于如何解决这个问题的见解?我声明模型的方式有问题吗?

编辑:应该注意,此模型上的其他调用(如 fetch 或 sync)会引发相同的错误,即使原始 fetch 工作没有问题。

EDIT2: 嗯,还没有完全出锅,但是我改变了定义模型 url 的方式,使用 urlRoot 和“id”属性,现在 DELETE 请求被发送到服务器没有错误。

【问题讨论】:

    标签: backbone.js views models


    【解决方案1】:

    defsq 答案很好。唯一缺少的是在模型上定义idAttribute,因为它不是基于约定的id 字段,而是uid

    MessageManager.models.Conversation = Backbone.Model.extend({
        idAttribute: 'uid',
        defaults: {
            uid: '',
            title: '',
            messages: [],
            users: [],
            dateUpdated: null,
            isNew: true,
            message: ''
        },
        urlRoot: "/api/conversations"
    });
    

    您不需要手动附加“id”。只需告诉 Backbone 你的 id 属性是uid,其他一切都可以。事实上,如果它在内部存储为uid,您可以事件调用mymodel.id 来获取模型事件的id。 :)

    http://backbonejs.org/#Model-idAttribute

    我个人不喜欢所有的默认值。如果您不设置默认值,则所有内容都将是 undefined,您可以简单地使用 if 进行防范(未定义是 falsey 值)。

    if(!model.get("messages")){
       //no messages
    }
    

    【讨论】:

    • 我正在寻找如何使用 idAttribute!非常感谢!
    • 然后标记为已回答,以供未来用户查找。乐意效劳! ;)
    【解决方案2】:

    这是因为您必须指定模型的 urlRoot 属性。没有它url 不被考虑。所以试试这个吧:

    MessageManager.models.Conversation = Backbone.Model.extend({
        defaults: {
            uid: '',
            title: '',
            messages: [],
            users: [],
            dateUpdated: null,
            isNew: true,
            message: ''
        },
        urlRoot: function() {
            var url = '/api/conversations';
            if (this.get('uid').length > 0) url += '/'+this.get('uid');
            return url;
        }
    });
    

    文档says:

    urlRootmodel.urlRoot 或 model.urlRoot() 如果您使用集合之外的模型,请指定 urlRoot,以启用默认 url 函数以根据模型 ID 生成 URL。 “[urlRoot]/id” 通常,您不需要定义它。注意 urlRoot 也可能是一个函数。

    以及Backbone.Model url 方法的源代码:

    url: function() {
      var base =
        _.result(this, 'urlRoot') ||
        _.result(this.collection, 'url') ||
        urlError();
      if (this.isNew()) return base;
      return base.replace(/([^\/])$/, '$1/') + encodeURIComponent(this.id);
    },
    

    【讨论】:

    • 我添加了 urlRoot 属性,我没有错误了。但是,“destroy”函数并没有在服务器上调用 DELETE 方法,而是直接成功,并带有未定义的响应。内部似乎仍然出现问题,我该如何弄清楚是什么?此外,成功调用不会执行其余调用(如同步和导航),考虑到 console.log 调用仍然会发生,这非常奇怪。就好像在这个电话之后,骨干变得完全麻木了。
    猜你喜欢
    • 2012-04-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-11
    • 1970-01-01
    • 2012-12-11
    • 1970-01-01
    相关资源
    最近更新 更多