Using Backbone.js models and collections with Qt and QML

Backbone QML TodoI have been a big fan of Backbone.js a long time. Together with Marionette.js it offers a solid toolkit to front-end web developers.

Lately I have worked with Qt and QML. With QML you can create nice user interfaces very easily, but what I have missed is that easy integration to backend applications. So I thought what if I try to use models and collections of backbone.js. I was quite a skeptical first, because backbone.js depends on jQuery with uses window and document objects that are not working in Qt. However I decided to try it.

Instead of jQuery, I grabbed Zepto.js that offers the same API as jQuery. I tuned the library slightly to get rid of errors related to window and document objects. There were not many of them.

Then I took underscore.js that backbone.js uses and finally backbone.js itself. I made slight changes to get them initialise correctly, but nothing big changes there.

After that I only needed to implement a simple application where I could test that everything is working. The result was much better than I expected. You can use directly Backbone’s collections and models with your Qt application and even listen events in your QML file, they just work.

https://github.com/nevalla/qml-backbone-todo

Define backbone models and collections
// app.js
var baseUrl = "https://api.engin.io/v1";
var Todo = Backbone.Model.extend({

});

var TodosCollection = Backbone.Collection.extend({
model: Todo,
url: baseUrl+”/objects/todos”,

parse: function(response) {
return response.results;
}
});

2. Use models and collections in QML file

//main.qml
function completeItem(index) {
var todo = App.todos.at(index)
todo.save({completed: true}, {
success: function(model) {
todoModel.setProperty(index, "itemProcessing", false);
},
error: function(){ console.log("error")}
} )
todoModel.set(index, todo);
}

3. Listen collection events in QML file

//main.qml
ListModel {
id: todoModel
}
Component.onCompleted: {
App.todos.on("add", function(todo) { todoModel.append(todo) });
App.getTodos();
}

So the first impact was very positive. I haven’t tested all functions of Backbone.js yet, so there may be some errors. However I don’t believe there are any fundamental errors that prevent using Backbone.js.

How to implement TreeView with Backbone.js

I started to implement an application that uses backbone.js. One feature that I needed was some kind of treeview as a side menu. I searched some jQuery based treeviews (like jstree and jQuery plugin: Treeview) but they were not suitable as out of the box.

Finally I decided to implement feature by myself. I found that jstree had a very good model of <ul> and <li> element combinations and I went to that direction in my solution as well. See the DEMO

Basically I needed two Backbone View classes: TreeView and TreeViewItem.

TreeView

TreeView class just creates the master <ul>-element (templates/treeview/menu.jst.ejs)

<ul id="menu"></ul>

The class also fetches root level collection of MenuItems and creates TreeViewItem for each item.

TreeViewItem

TreeViewItem has one MenuItem model and a collection of TreeViewItems. In the template (templates/treeview/item.jst.ejs) name of the item is displayed and <ul> element is rendered as sub menu placeholder.

<ins>&nbsp;</ins>
<a href="#"><%= model.escape('name') %></a>
<ul></ul>

TreeViewItem handles clicks from arrow icon (<ins>-element has arrow image as a background) and opens/closes sub menu.

Both views extends Support.CompositeView (from backbone-support library).

Usage

application.js contains required libraries
backbone_treeview.js initializes TreeView class

window.BackboneTreeView = {
    Models: {},
    Collections: {},
    Views: {},

    menu: null,

    initialize: function() {

    },

    initializeMenu: function() {
        this.menu = new BackboneTreeView.Views.TreeView();
        this.menu.render();

    }

};
$(document).ready(function() {

    BackboneTreeView.initializeMenu();
});

How would you improve the implementation and should I make it as a library?

Link to project source: https://github.com/nevalla/backbone-treeview