Tabris.js Tips & Tricks: Parts 1 - 3

November 20, 2015 | 3 min Read

1 - A module for every page!

The Page widget and JS modules are a natural fit. The backbone of your Tabris.js App should consist of modules defining pages. For example ‘MyPage.js’:

exports.create = function( someData ) {
  var page = tabris.create("Page", { title: "My Page" });
  tabris.create("CollectionView", {
    items: someData,
    // ... etc ...
  // ... add some more widgets, apply layout, etc ...
  return page;

You can then use it like this:

require("./MyPage").create( data ).open();

2 - Give that back!

In the above example we give some data to the page, but what if you need to get some other data back to the module that opened the page? Well, since Tabris.js widgets can hold properties that aren’t pre-defined (i.e. “custom properties”), this is easy. First, set the data you want to return (e.g. the name of a person) as a custom property of the sub page before you close it.

exports.create = function( someData ) {
  var page = tabris.create("Page", { title: "My Page" });
  // ...
  someWidget.on("someEvent", function(person) {
    page.set("es-person", person).close();

Since Tabris.js never uses dashes in its own property names, giving a custom property a dash-separated prefix will rule out any future name collisions. You may use the initials of your company or project (here: “EclipseSource” -> “es-” ), or just a dash (e.g. “-person”).

Then, to get the data in the previous page, listen to the “dispose” event that is fired once the sub page closes:

require("./SubPage").create( data ).open().once("dispose", function() {
  if(tabris.ui.get("activePage") === page) { // assuming this is another page module
    var person = this.get("es-person");
    if( person ) {
      // ...

The commented line can be left out if you want to react to the data even if the user navigates from the sub page directly to a (another) top-level page, not the page that opened it.

3 - But you don’t need this!

By default the this keyword in a Tabris.js event listener will reference the object that fired the event, because in most cases that is what you would naturally expect. (See above example). However, this is tricky in JavaScript, as it can point to different objects depending on how the function is called. For example, you can change to what it points to on the event registration.

require("./SubPage").create( data ).open().once("dispose", function() {
  var person = this.get("es-person");  // CRASHES... 
}, {}); // ... because of this easily missed third parameter

However, the sender of an event is always the first parameter given to a listener, allowing for “thisless” programming:

require("./SubPage").create( data ).open().once("dispose", function(subPage) { 
  var person = subPage.get("es-person"); 
}, {});

That way you also don’t have to put the sub page instance into a local variable, and it is always a good idea not having too many of those in your module.