Использование функции инициализации в Backbone Router

Я занимаюсь созданием своего первого магистрального приложения с использованием Node/express и Mongodb. Приложение представляет собой онлайн-меню еды и систему заказов, которая собирает все данные из mongo при загрузке первой страницы и помещает их в коллекцию Backbone. Я использую функцию инициализации в магистральном маршрутизаторе для извлечения () данных и помещения их в коллекцию. Моя проблема в том, что индексный маршрутизатор загружается до завершения функции Initialize. Я подтвердил, что функция инициализации работает правильно, потому что я могу получить доступ к коллекции в консоли браузера.

Я могу ошибаться, но вот упрощенная версия моего маршрутизатора:

GDB.Router = Backbone.Router.extend ({
    routes: {
        '': 'index',
        'drinks': 'drinks'
    },

    meals: {},

    initialize: function() {
        meals = new GDB.Collections.Meals
        meals.fetch();
    }, 

    index: function() {
            var mealsView = new GDB.Views.Meals ({collection: meals});
            $('#GDBContainer').append(mealsView.render().el);           
    },

    drinks: function() {
            var drinksView = new GDB.Views.Meals ({collection: meals.byCategory('drinks')});
            $('#GDBContainer').append(drinksView.render().el);
    }
});

person James Billings    schedule 17.04.2013    source источник


Ответы (2)


Скорее всего, функция initialize завершилась до вызова функции index, но ваша fetch является асинхронной, поэтому коллекция не завершает загрузку, когда вы пытаетесь отобразить mealsView.

GDB.Router = Backbone.Router.extend ({
    routes: {
        '': 'index',
        'drinks': 'drinks'
    },

    initialize: function() {
        this.meals = new GDB.Collections.Meals
        // fetch returns a jquery promise
        this.fetchingMeals = this.meals.fetch();
    }, 

    index: function() {
            var self = this;
            // maybe show loading spinner here
            $('#GDBContainer').html('<div>Loading</div>');

            this.fetchingMeals.done(function(){
                // now this.meals is done fetching!
                var mealsView = new GDB.Views.Meals ({collection: self.meals});
                $('#GDBContainer').html(mealsView.render().el);  
            });         
    },

    drinks: function() {
            var self = this;
            // maybe show loading spinner here
            $('#GDBContainer').html('<div>Loading</div>');

            this.fetchingMeals.done(function(){
                var drinksView = new GDB.Views.Meals ({collection: self.meals.byCategory('drinks')});
                $('#GDBContainer').html(drinksView.render().el);
            });
    }
});
person Paul Hoenecke    schedule 17.04.2013
comment
У меня было похожее решение, но я поместил метод выборки в каждый из методов маршрутизатора. Проблема в том, что делается запрос ajax, и коллекция повторно заполняется каждый раз, когда вы меняете маршруты, что противоречит цели коллекции, когда у меня уже есть все, что мне нужно внутри нее. Я надеялся, что Backbone будет откладывать запуск любого метода маршрутизатора до тех пор, пока не завершится выполнение метода инициализации и всего, что внутри него. Спасибо за помощь! - person James Billings; 17.04.2013

Вы можете использовать решение Пола или прослушивать события добавления/сброса/любых событий коллекции в представлении.

view.listenTo(model, 'reset', view.render);
person yujingz    schedule 17.04.2013