문제

I have one container for data ( #data ) and simple router for filling this:

var Router = Backbone.Router.extend({
    routes: {
        '': 'list',
        ':id': 'single'
    },
    single: function(id) {
        $('#data').empty();
        var applicationModel = new applications.Models.application();
        applicationModel.fetch({
            data: {
                id: id
            }).then(function() {
            var applicationView = new applications.Views.application({
                model: applicationModel
            });
            $('#data').append(applicationView.render().el);
        });
        }, list: function() {
            $('#data').empty();
            var applicationsCollection = new applications.Collections.applications();
            applicationsCollection.fetch().then(function() {
                var applicationsView = new applications.Views.applications({
                    collection: applicationsCollection
                });
                $('#data').append(applicationsView.render().el);
            });
        }
    });

Initially I'm on list route. I click a link to the single route for display single item and then immediately press 'Back' button (going back to list route). The problem is then these both actions are getting mixed. Kind of. Because of asynchronous behavior, the single action response is being mixed with the current list view. And I'm seeing both results in one route.

http://joxi.ru/6FApUxjKTJAYNk_vbKQ - clear list route

http://joxi.ru/UlEpU_3JTJAgdOsGbY0 - clear single route

http://joxi.ru/jFEpUxjKTJAeNt5Ptw8 - mixed routes ?!

How to disable single route callback if i back to list route?

도움이 되었습니까?

해결책

I think you should approach the problem of using backbone's router differently. You should separate your app's view, router and model. One app model can be shared between the router and the view.

var AppModel = Backbone.Model.extend({
    defaults: {
        view: '',
        // should hold any additional params for the view
        viewParams: {}
    }
});

You should create an AppView that will display a relevant view according to the model. Each subView (SingleView, ListView), should create its own models/collections and initiates the fetch calls.

var AppView = Backbone.View.extend({
    id: '#data',
    initialize: function() {
        this.listenTo(this.model, 'change:view', this.renderView);
    },
    views: {
        'list': ListView,
        'single': SingleView
    },
    renderView: function(model, view) {
        // create the appropriate view
        // remove the current view, any listeners to it
        // each view should create it's own models and initiate fetch
        // the selected view dom "el" should be appended to this.el (appview) view
    }
});

The router should only update the model with relevant data, and in your case:

var AppRouter = Backbone.Router.extend({
    routes: {
        '': 'list',
        ':id': 'single'
    },
    initialize: function(options) {
        this.model = options.model;
    },
    list: function() {
        this.model.set({
            view: 'list'
        });
    },
    single: function(id) {
        this.model.set({
            viewParams: {
                id: id
            }
        });
        this.model.set({
            view: 'single'
        });
    }
})
var app = {};
app.model = new AppModel();
app.view = new AppView({
    model: app.model
});
app.router = new AppRouter({
    model: app.model
});

you can further read the following posts i wrote about using backbone for application architecture:

  1. Backbone Router The Important Role Of A Controller
  2. Backbone JS For Large Scale Applications UI Architecture
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top