backbone.js должно быть определено свойство URL

Я пытаюсь использовать Backbone.localStorage в качестве серверной части приложения.

Я написал модель под названием Era и соответствующий EraView. Нажатие ввода в EraView приводит к сохранению модели, и здесь я получаю сообщение об ошибке:

Uncaught Error: A "url" property or function must be specified 
urlError     backbone.js:1509
_.extend.url     backbone.js:515
_.result     underscore-min.js:1060
Backbone.sync     backbone.js:1410
Backbone.sync     backbone.localStorage.js:188
_.extend.sync     backbone.js:276
_.extend.save     backbone.js:476
karass.EraView.Backbone.View.extend.close     era.js:61
karass.EraView.Backbone.View.extend.updateOnEnter     era.js:75

Вот код EraView

var karass = karass || {};

// Era Item View

// the DOM element for an era item
karass.EraView = Backbone.View.extend({
    tagName: 'li',
    className: 'era',
    template: _.template( $('#era-template').html() ),

    // The DOM events specified to an item
    events: {
        'dblclick .edit-input': 'edit',
        'keypress .edit-input': 'updateOnEnter',
        //'blur .edit': 'close',
    },

    // The EraView listens for changes to its model, re-rendering. Since there's
    // a one-to-one correspondence between an era and a EraView in this karass, 
    // we set a direct reference on the model for convenience.
    initialize: function(){
        _.bindAll(this);
        this.model.on('change', this.render, this);
    },

    // Re-renders the era item to the current state of the model and
    // updates the reference to the era's edit input within the view
    render: function(){
        this.$el.html( this.template(this.model.attributes));
        this.$era_start = this.$('.era-start');
        this.$era_end = this.$('.era-end');

        this.$era_start.attr('disabled', true);
        this.$era_end.attr('disabled', true);

        return this;
    },

    // Switch this view into editing mode, displaying the input field
    edit: function(){
        this.$('.edit-input').removeAttr('disabled');

        this.$el.addClass('editing');
        this.$('.edit-input').addClass('editing');
    },

    // Close the editing mode, saving changes to the era
    close: function(){
        this.$('.edit-input').attr('disabled', true);

        var start = this.$era_start.val().trim();
        var end = this.$era_end.val().trim();

        if(start && end){
            this.model.save({from: start, until: end});
        }

        this.$el.removeClass('editing');
        this.$('.edit-input').removeClass('editing');

        this.trigger('close');
    },

    updateOnEnter: function(e){
        if(e.which !== ENTER_KEY && (!this.$era_start.val().trim() || !this.$era_end.val().trim())){
            return;
        }

        this.close();
    }
});

А это код модели эпохи:

var karass = karass || {};

karass.Era = Backbone.Model.extend({

    defaults: {
        from: '', 
        until: ''
    },

});

Я думал, что мне не нужен URL-адрес при использовании localStorage.

Редактировать: я забыл упомянуть, что хотя это происходит в самой Era/EraView, оно также происходит в модели Name, которая расширяет Era. Name, в свою очередь, принадлежит коллекции Names. Я не знаю, имеет ли это значение, но я решил добавить это.

Правка 2. Коллекция Names выглядит следующим образом:

karass.Names = History.extend({

    model: karass.Name,

    localStorage: new Backbone.LocalStorage('karass-names'),

});

Изменить 3: я разместил весь код на jsfiddle: http://jsfiddle.net/herrturtur/CRv6h/


person lowerkey    schedule 02.02.2013    source источник


Ответы (1)


Вам не нужен URL-адрес при использовании localStorage. Но вам нужно установить свойство localStorage в вашей модели или в вашей коллекции (если вы установите localStorage в коллекции, модели внутри коллекции «наследуют» этот параметр):

karass.Era = Backbone.Model.extend({

    localStorage: new Backbone.LocalStorage("EraCollection"), 
    // the EraCollection should be an unique name within your app.

    defaults: {
        from: '', 
        until: ''
    },

});

Если вы не настроите свойство localStorage, плагин вернется к синхронизации ajax по умолчанию, поэтому вы получите исключение отсутствия uri.

person nemesv    schedule 02.02.2013
comment
ага, сделал это. (Надо было также опубликовать код коллекции имен) - person lowerkey; 02.02.2013
comment
Подожди, эпоха - это не коллекция. Это модель, которая расширяется именем, которое, в свою очередь, входит в коллекцию имен. В этой коллекции Names определено свойство localStorage. - person lowerkey; 02.02.2013
comment
Извините, но я не слежу за вами, какой класс вашего расширения какой и к какой коллекции принадлежит... что верно, что из сообщения об исключении, что в вашем EraView объект в this.model не имеет свойства localStorage и не принадлежит к коллекции, которая имеет localStorage. Вы должны дважды проверить, что все ваши коллекции имеют localStorage, и вы только если передаете модель в представление, эта модель находится внутри коллекции. - person nemesv; 02.02.2013
comment
В противном случае вам нужно опубликовать полную иерархию моделей/коллекций, а также то, что вы передаете в свой EraView как модель... - person nemesv; 02.02.2013
comment
Эра расширяет модель; Имя расширяет Эру; Имена: коллекция имен, имеет свойство localStorage; Так вы говорите, что каждая модель должна принадлежать коллекции? this.model в EraView — это, по сути, объект Name, принадлежащий коллекции со свойством localStorage. - person lowerkey; 02.02.2013
comment
Что-то неправильно подключено в вашем коде... Плагин localStorage проверяет model.localStorage или, если он не определен, он проверяет model.collection.localStorage, попробуйте записать эти два значения console.log(this.model.localStorage) if (model.collection) console.log(this.model.collection.localStorage) перед вызовом this.model.save - person nemesv; 02.02.2013
comment
@lowerkey код в вашей скрипке подключен правильно. Вы просто нигде не вызываете save... Я заменил вызовы set на вызовы save в этой скрипте: jsfiddle. net/pLBjb и хранит ваши модели в локальном хранилище. Вы можете проверить в консоли chrome dev. Или просто создайте несколько записей и перезагрузите страницу... - person nemesv; 02.02.2013
comment
давайте продолжим это обсуждение в чате - person lowerkey; 02.02.2013