错误:A" url"必须指定属性或函数,但指定了url

时间:2014-10-16 09:16:52

标签: backbone.js views models

我有一个Conversation模型和一个显示此模型的视图。从服务器获取此模型没有任何问题(url属性可以正常工作),并呈现视图。 但是,当我试图在视图的函数中销毁模型时,我得到错误'A“url”属性或函数必须指定',即使我在destroy调用之前显示所述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/');
            }
        });
    }
});

任何人都可以就如何解决此问题提供一些见解吗?我宣布模型的方式有问题吗?

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

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

2 个答案:

答案 0 :(得分:1)

这是因为您必须指定模型的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);
},

答案 1 :(得分: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,其他所有内容都可以使用。实际上,如果事件调用mymodel.id在内部存储为uid,则可以事件调用undefined来获取模型的标识。 :)

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

我个人不喜欢所有的默认值。如果您没有设置默认值,那么一切都将是falsey,您可以使用if(undefined is if(!model.get("messages")){ //no messages } 值来防范。)

{{1}}