0

I have this fairly simple controller+router below for example purposes. My question is: How do I deal with the router and Backbone.history if I have modified a certain model?

Let's say that I fire up a router and a controller. The default route "" brings me to the function blue where I set the background to the color blue. I can click on a button that will bring me to the function red where it sets the background red and the URL to /#red.

If I click the back button, I will go back to my "" url, but the background will stay red. Is there a way of getting the previous state and not only change the URL when dealing with the history?

I understand that in function blue, I could just set the background to be blue and not to this.model.get("background), but I am asking in more complex cases, how to get the previous state of this.model through the Backbone.history.

MyApp.module('Main', function (Main, MyApp, Backbone, Marionette, $, _){

    Main.Router = Marionette.AppRouter.extend({
        appRoutes: {
             "": "blue",
            "red": "red"
        }
    });

    Main.Controller = Marionette.Controller.extend({
        start: function() {
            console.log("MyApp Controller start...");

            this.model = new Backbone.Model({background: "blue"});

            Backbone.history.start()
        },

        blue: function() {
            $("body").css("background-color", this.model.get("background"));            

            $("#button").click(function() {
                //MyApp.router.navigate("red", {trigger: true});
                MyApp.controller.red();
            });
        },

        red: function() {
            this.model.set({background: "red"});
            $("body").css("background-color", this.model.get("background"));
            MyApp.router.navigate("red");
        }
    });
});
  • 1
    You can try [previousAttributes](http://backbonejs.org/#Model-previousAttributes) but it sounds like what you have is a bit of a design flaw to begin with. If you need fully versioned model attributes you might want to create your own datastructure for that and have the model hold the current state and not the entire history. – ivarni Oct 27 '15 at 16:18
  • It is likely I don't fully understand MVC then. How would you deal with this situation: 1. router calls a controller method that shows a view from a model 2. user deletes model with a click and it changes url 3. user wants to go back and see the model he just deleted. – Nicolas Truong Oct 27 '15 at 16:27
  • I have an answer here - http://stackoverflow.com/a/33327942/132829 =- that may be helpful to you. There's a very similar set up with Marionette Router and Controller, which handles opening any route directly, and back/forward buttons work too. – Yura Oct 27 '15 at 16:45
  • 1
    There's no one true way to do MVC, you have variations like MVP, MVVM, MVA etc. In Backbone you usually want your models to be backing the view you're currently showing. In the case you describe I'd mosy likely just use an array and push `model.attributes` onto it when I wanted to save state, and then pop from that array and use `model.set` to restore state. You may or may not want to keep that history on the server, it depends on how far you want to stray from being a pure RESTful CRUD app. – ivarni Oct 27 '15 at 18:25

1 Answers1

1

MyApp.router.navigate("red"); - That only changes the url but doesn't actually trigger your controller method to be fired. You might be tempted to set {trigger:true} option, but avoid that.

Just call the controller method for that route. I have a very similar working example setup in my answer here: How can I show and hide regions in Marionette.js?

The truth is there are several things messed up in your code example. Like, you shouldn't be setting click handles in your controller, that's a view's job. Controllers should just do the most abstract job, like cleaning up and rendering a view. Actual user interaction should be handled in views.

Community
  • 1
  • 1
Yura
  • 2,690
  • 26
  • 32
  • I knew about the `{trigger: true}` and that is why I didn't include it in my example. Also, I do know about views, but the button was just a quick dirty solution to show that a model was being changed. Although I thank you for linking me that answer, my question was more related to the history. Assuming that a model has changed and triggered an event that modified a view, how can I get the old state of the model assuming a user clicked "back" and show the old view, before the event triggered. – Nicolas Truong Oct 28 '15 at 01:00