Error: A “url” property or function must be specified, except url is specified

六眼飞鱼酱① 提交于 2019-12-22 00:10:04

问题


I have a Conversation model and a view that displays this model. This model is fetched from the server without any problem (the url property works fine then), and the view is rendered. However, when I attempt to destroy the model in a function of the view, I get the error 'A "url" property or function must be specified', even though when I display said url right before the destroy call, it is exactly the url it should be.

Here is the code for the model:

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

And the view:

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/');
            }
        });
    }
});

Can anyone give some insight on how to resolve this problem? Is there something wrong in the way I declare the model?

EDIT: It should be noted that other calls (like fetch or sync) on this model fire the same error, even though the original fetch works without a problem.

EDIT2: Well, not completely out of the frying pan yet, but I changed the way I defined the model's url, using urlRoot and the "id" attribute, and now the DELETE request is sent to the server without error.


回答1:


defsq answer is good. The only thing missing is to define the idAttribute on your model, since it's not the convention-based id field, but uid.

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

You don't need to append the "id" manually. Just tell Backbone that your id attribute is uid and everything else will work. In fact, you can event call mymodel.id to get the id of the model -event if it's stored internally as uid. :)

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

Personally I don't like all that default values. Everything will be undefined if you don't set default values, which you can simply guard against with an if (undefined is a falsey value).

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



回答2:


It happens because you have to specify urlRoot property of the model. Without it url is not considered. So try this maybe:

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

Documentation says:

urlRootmodel.urlRoot or model.urlRoot() Specify a urlRoot if you're using a model outside of a collection, to enable the default url function to generate URLs based on the model id. "[urlRoot]/id" Normally, you won't need to define this. Note that urlRoot may also be a function.

And source code for Backbone.Model url method:

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


来源:https://stackoverflow.com/questions/26400601/error-a-url-property-or-function-must-be-specified-except-url-is-specified

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!