Working with Backbone Routers

Let's imagine that you have a list and a template and you want to show either one or another by clicking on their elements. There you can have different patterns depending on how you initialize the components:

Backbone Router for Pure Webix Views

To create a UI we can use a Webix code like the following:

webix.ui({
  container:"app1_here", rows:[
     {template:"Click on item", type:"header" },
     {cells:[
       {view:"list", url:"data.json", template:"#title#", select:true, id:"mylist"},
       {template:"<button onclick='history.back()'>Back</button>", id:"details" }
    ]}
  ]
});

Now, let's create a Backbone Router.

var routes = new (Backbone.Router.extend({
    routes:{
        "":"index", 
        "films/:id":"details" //details() f-n is triggered
    },
    details:function(id){
        $$("details").show(); //it shows template with film details
    },
    index:function(){
        $$("mylist").show();
    }
}));

As you can see the router shows the necessary view based on the current document URL. After switching to the "details" template, the application receives a hashbang URL localhost/myapp.html#films/id showing the ID of a currently selected list item (last segment).

To have the app working we need to add a few extra lines of code:

$$("mylist").attachEvent("onAfterSelect", function(id){  //navigation rule
    routes.navigate("films/"+id, { trigger:true }); 
});
Backbone.history.start(); //router starts memorizing its steps

Related sample: Routes.The Webix way

These lines define the navigation rule after selecting an item in the list and start the router. Template, in its turn, uses an existing router and makes a step back on button click (look at its code above).

BackBone Router for Backbone-integrated Views

Now let's try to recreate the same app, but stick closer to the native Backbone approach. Instead of creating Webix UI directly, let's define Backbone-Webix integrated views for both states:

var layout = new WebixView({
    el:"#app1_here",
    config:{
        rows:[
            { template:"Click on item", type:"header" },
            {
                view:"list", url:"common/data.json",
                template:"#title#", select:true,
                id:"mylist"
            }
        ]
    }
});
 
DView = Backbone.View.extend({
    el:"#app1_here", //the same element as above
    tagName: "div",
    render: function(){
        $(this.el).html("<button onclick='history.back()'>Back</button>");
    },
});
var template = new DView();

Now a router looks a bit more different:

var routes = new (Backbone.Router.extend({
    routes:{
        "":"index", 
        "films/:id":"details" //details() f-n is triggered
    },
    details:function(id){
        template.render(); //it renders the template into its "el"
    },
    index:function(){
        layout.render(); //rendering layout back
        //attaching select event after rendering 
        $$("mylist").attachEvent("onAfterSelect", function(id){
            routes.navigate("films/"+id, { trigger:true });
        });
    }
}));

Related sample: Routes.The Backbone way

Instead of switching between views in Webix layout we are rendering different Backbone Views into one and the same element depending on the current state. Still, the resulting behavior is the same.

Yet, the router should be triggered separately once the app has been initialized:

//initializing app
Backbone.history.start();

Updating Layout Section

When using views we can update not only the top view, but any section of Webix layout in it.

Let's create 3 views, one is layout and the other two (list and template) are children of this layout. They will be shown in this layout in different cases:

var template = new WebixView({
    config:{ template:"<button onclick='history.back()'>Back</button>" }
});
var list = new WebixView({
    config:{
        view:"list", url:"common/data.json",
        template:"#title#", select:true,
        id:"mylist"
    }
});
//layout with Webix config
var layout = new WebixView({
    el:"#app1_here",
    config:{
        rows:[
            { template:"Click on item", type:"header" },
            { }
        ]
    }
});

The router for such pattern is as follows:

var routes = new (Backbone.Router.extend({
    routes:{
        "":"index", 
        "films/:id":"details"
    },
    details:function(id){
        //setting node for template as layout child view 
        template.el = layout.root.getChildViews()[1]; 
        template.render();
    },
    index:function(){
        //setting node for list as layout child view 
        list.el = layout.root.getChildViews()[1];
        list.render();
        $$("mylist").attachEvent("onAfterSelect", function(id){
            routes.navigate("films/"+id, { trigger:true });
        });
    }
}));

The code above locates the necessary cell in the layout and renders the needed view into the target cell.

Related sample: Routes.Changing the Webix Layout

Back to top