Грешка: Трябва да се посочи свойство или функция url, освен че е посочен url

Имам модел на разговор и изглед, който показва този модел. Този модел се извлича от сървъра без проблем (свойството url работи добре тогава) и изгледът се изобразява. Въпреки това, когато се опитам да унищожа модела във функция на изгледа, получавам грешката „Трябва да се укаже свойство или функция „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/');
            }
        });
    }
});

Може ли някой да даде представа как да се реши този проблем? Има ли нещо нередно в начина, по който декларирам модела?

РЕДАКТИРАНЕ: Трябва да се отбележи, че други повиквания (като извличане или синхронизиране) на този модел предизвикват същата грешка, въпреки че оригиналното извличане работи без проблем.

EDIT2: Е, все още не съм напълно излязъл от тигана, но промених начина, по който дефинирах URL адреса на модела, използвайки urlRoot и атрибута "id", и сега заявката за ИЗТРИВАНЕ се изпраща до сървъра без грешка.


person Gabriel Theron    schedule 16.10.2014    source източник


Отговори (2)


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. :)

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

Лично аз не харесвам всички тези стойности по подразбиране. Всичко ще бъде undefined, ако не зададете стойности по подразбиране, срещу които можете просто да се предпазите с ако (недефинирано е стойност falsey).

if(!model.get("messages")){
   //no messages
}
person CharlieBrown    schedule 16.10.2014
comment
Търсех как се използва idAttribute! Благодаря много! - person Gabriel Theron; 16.10.2014
comment
След това маркирайте като отговорено, за да разберат бъдещите потребители. радвам се да помогна! ;) - person CharlieBrown; 16.10.2014

Това се случва, защото трябва да посочите 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;
    }
});

В документацията се казва:

urlRootmodel.urlRoot или model.urlRoot() Посочете urlRoot, ако използвате модел извън колекция, за да активирате url функцията по подразбиране за генериране на 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);
},
person dfsq    schedule 16.10.2014
comment
Добавих атрибута urlRoot и вече нямам грешка. Въпреки това, вместо да извика метода DELETE на сървъра, функцията за унищожаване отива директно към успех с недефиниран отговор. Изглежда, че нещо все още се обърка вътрешно, как бих могъл да разбера какво? Също така извикването за успех не изпълнява останалите повиквания (като синхронизирането и навигацията), което е изключително странно, като се има предвид, че извикването на console.log все още успява да се случи. Сякаш гръбнакът напълно изтръпна след това обаждане. - person Gabriel Theron; 16.10.2014