Article

Sencha Touch for the PHP Developer

The beginning of the year saw me working on the latest version of the Herald Scotland app (both android and iOS versions were released at the beginning of May) using Sencha Touch and PhoneGap. App development is not one of my primary skills and the learning curve from my comfort zone of PHP to Sencha Touch has been a steep one and one which I'm still far from conquering, however I thought it might be useful to share some of what i have learned and hopefully steers others away from some of the issues I encountered.

So you can build a website?

If you only take away one thing from this article then it should be to forget everything you know about web development and start again... Sencha Touch is an entirely different beast to what you are used to.

With Sencha Touch the page is built from a collection of javascript files which create the output of the page so there is no nice easy HTML file to work with.  You should hopefully already be familiar with a DOM inspector and this will be your best friend when trying to figure out how all the pieces related.

If you consider a standard page within a website you will notice each page has a similar flow i.e. header, main content, footer

traditional-page.jpg

In a Sencha Touch application the flow is a bit different (header, a container for the main content, footer).

sencha-page.jpg

The main difference is to do with the container to hold the main content. To view several pages on a website each page is loaded in turn and the header, main content and footer is generated and added to your page. In your Sencha Touch app only 1 page is loaded, 1 header and footer is generated and the main content for several pages is added or removed from the main content container as and when required.

If you were to follow the process of a traditional webpage in Sencha Touch you would have several headers and footers and if you had any listeners in them then you would also be listening to several instances of the same listener.

Understand what markup is necessary

Using an Ext.List is a perfect way to display a list of content i.e. a list of news articles, contacts, sports teams etc, but here you must again refrain from trying to do exactly as you would do when creating a list on a traditional webpage i.e. On a traditional webpage you may have something like the following for each article

<div class="item">
    <h2><a href="...">[First Name] [Last Name]</a></h2>
</div>

But within the itemTpl of an Ext.List you have to remember the whole item is treated as the equivalent of an A link, more accurately, clicking the item triggers an event listener which you can attach logic to.  As a result, to use the example above in an Ext.List itemTpl you should use the above without any A tags and make use of the itemtap event to determine what to do.

Although the example below is a bit longer than the HTML version above, the key point is the itemTpl line as you will notice there is no <a href> but we are able to determine which item is clicked by the itemtap listener.

Ext.application({
   launch: function() {
       Ext.define('Contact', {
           extend: 'Ext.data.Model',
           config: {
               fields: ['firstName', 'lastName']
           }
       });

       var store = Ext.create('Ext.data.Store', {
           model: 'Contact',
           sorters: 'lastName',
           grouper: {
               groupFn: function(record) {
                   return record.get('lastName')[0];
               }
           },
           data: [{
               firstName: 'Tommy',
               lastName: 'Maintz'
           }, {
               firstName: 'Rob',
               lastName: 'Dougan'
           }, {
               firstName: 'Ed',
               lastName: 'Spencer'
           }, {
               firstName: 'Jamie',
               lastName: 'Avins'
           }, {
               firstName: 'Aaron',
               lastName: 'Conran'
           }, {
               firstName: 'Dave',
               lastName: 'Kaneda'
           }, {
               firstName: 'Jacky',
               lastName: 'Nguyen'
           }, {
               firstName: 'Abraham',
               lastName: 'Elias'
           }, {
               firstName: 'Jay',
               lastName: 'Robinson'
           }, {
               firstName: 'Nigel',
               lastName: 'White'
           }, {
               firstName: 'Don',
               lastName: 'Griffin'
           }, {
               firstName: 'Nico',
               lastName: 'Ferrero'
           }, {
               firstName: 'Jason',
               lastName: 'Johnston'
           }]
       });

       Ext.create('Ext.List', {
           fullscreen: true,
           itemTpl: '<div class="item"><h2>{firstName} {lastName}</h2></div>',
           store: store,
           grouped: true,
           listeners: {
               itemtap: function(view, index, item, e){
                   Ext.Msg.alert(e.data.firstName);
               }
           }
       });
   }
});

Source available at https://fiddle.sencha.com/?fiddle=6he#fiddle/6he

Example adapted from https://try.sencha.com/touch/2.0.1/docs/Ext.dataview.List.2/viewer.html"ltr">Sencha Touch has a good set of tools available for helping you develop your app and you should get familiar with what tools are available and what they can do for you.  Sencha CMD provides a command line tool for generating your app and preparing it for release.  In the early stages of building my first version of the app I wasn’t aware of the Sencha CMD command line tools and later when I tried to use Sencha CMD with my app it was a nightmare and I basically had to create a new app using Sencha CMD and then import my code into the new app.  Test early and test often and it’ll save headaches further down the line.

It’s also worth taking a little time to get familiar with the tools can do.  I lost a day or so when trying to package up the app for release as I was using

sencha app build production

instead of

sencha app build package

(Think website application vs Android / iOS app)

Sencha Touch also has a really good documentation along with examples and an active forum and although it can take a bit of time to work out some of the solutions that have been posted it does help to shed light onto lots of issues you may encounter.

Program Flow & Callbacks, Callbacks, Callbacks

In PHP we are used to a sequential program flow… the next code statement is run only when the current one is complete and if we call a method we get the response of that method before we continue on with the next code statement.  

Sencha Touch follows an asynchronous program flow which can cause some strange issues if you don’t take this into account.  For example, when you call a method within your code, the logic within that method is executed but the application also continues onto the next line of code after the method call without waiting for a response to be returned.  This can cause race conditions as if a subsequent action is dependant on the response from that method then this may not be set correctly, especially if the function takes time to run.  This can be demonstrated in the following (over-simplified) example:-

Ext.application({
    name: 'Program Flow Example Without Callback',

    launch: function() {
        this.firstLine();
        this.secondLine();
    },

    firstLine: function(callback) {
        // Increment the counter slowly
        var counter = 0;
        for(i=0;i<=10;i++) {
            Ext.Function.defer(function() {
            	counter++;
                if(counter == 10) {
                    document.write('This is the first line<br>');
                }
            }, 100);
        }

    },
    secondLine: function() {
        document.write('This is the second line<br>');
    }
});

Source available at https://fiddle.sencha.com/?fiddle=6cp#fiddle/6cp

If this was run via PHP we would expect the output to be

This is the first line
This is the second line

However, as Sencha carries on executing the next line of code as soon as it calls your method call, we get

This is the second line
This is the first line

This drove me crazy for a while as in my case my application beat the race condition on one run but did not necessary beat the race condition on the next run, therefore giving me an very intermittent issue until I understood why it was occuring.  The resolution to this is to use a callback and depending on your application the callbacks can get nested quite deeply.  Taking the above example again, if we refactored it to use callbacks it might look like

Ext.application({
    name: 'Program Flow Example With Callback',

    launch: function() {
        var me = this;
        
        this.firstLine(function() {
            me.secondLine();
        });
    },

    firstLine: function(callback) {
	// Increment the counter slowly
        var counter = 0;
        for(i=0;i<=10;i++) {
            Ext.Function.defer(function() {
            	counter++;
                if(counter == 10) {
                    document.write('This is the first line<br>');

                    // Now run the second line function 
                    // (via the callback passed in)
                    callback();
                }
            }, 100);
        }

    },
    secondLine: function() {
        document.write('This is the second line<br>');
    }
});

Source available at https://fiddle.sencha.com/?fiddle=6cq#fiddle/6cq

This time, we pass a callback to firstLine which is use to execute secondLine at the appropriate point and now we get the out put in the correct sequence

This is the first line
This is the second line

Naming Convention

This one is more of a personal preference which spills over from my PHP development rather than a requirement of Sencha Touch.  Within the PHP framework we use we add a suffix of Controller, View, Model etc as required to our files which allows me to quickly identify which files are for what part of the application.

When starting out with Sencha Touch I quickly found it confusing trying to figure out which tab in my IDE was for which file when I had a controller, view & model all called Article.js.  This got even more confusing when I had separate tablet & mobile files but by simply adding Controller, View & Model to the end of the filename as appropriate all the confusion was removed.

me.jpeg

I am a web developer specialising in web driven applications using PHP, MySQL, Symfony and Zend and I am currently working for the The Drum in Glasgow, Scotland.

Most days I can be found frantically coding away with EuroDance in my ears and consuming what I hope to be a never ending supply of coffee... happy days!

Want more like this?

Keep up-to-date with latest news from Inside the Agency using any of the following services

Recent articles

The Iron Triangle - How does motivation emphasis create an agency environment?

I remember when I first heard about the Iron Triangle. It sounded sinister, Evil Empire like, and not really something I could embrace in my fluffy idealistic agency brain. Just to be clear in this article I am talking about the Project Management version, not the US political system version… which is sinister and is just like the Evil Empire.

ITA-motivation-illustration-20151120.jpg

Back then I was speaking to my then boss, a man who I credit with opening my eyes to a great deal to how an agency works and, more importantly, how it should work. He was explaining in typically simple eloquence, how he wanted us to set expectation with clients. 

Read more

The Adblock Wars - Stop blaming the victim!

Much to the dismay of the advertising and publishing industry, Adblock is indeed here to stay. But, what is the industry doing about it? For the most part, pointing the finger and accusing the end user of underhanded tactics. To that I say: Pot, meet Kettle.

ad-blocking-article

Over the last few months I have noticed an increasing number of articles surround Adblock usage, most of which are coming from advertisers and publishers perspective.  Within these articles the underlying theme is that Adblock is evil and people using it are:

Read more

Content is a very lonely king (and he needs some pants)

I was once told that If you put a £5 note for sale in the window, you can sell it for £5 or maybe even more, but if you put it way at the back of the shop, hidden away and try to sell it for 50p, it still won't sell.

king_of_no_pants_by_pixiepirate.jpg

Lesson:  No matter how good the product is, if it's not where your customers can see it then it's worthless. 

Read more

Advertisement

Digital Ocean

Chris's Reading List

JAXenter

Self-promotion is a skill, but is that the skill you're looking for? - JAXenter

Do you want to hire somebody that's good at self-promotion, or are you looking for a certain skill-set? Perhaps you need to shape your job spec differently. Read more

TechCrunch

TechCrunch

When Crowdfunding Fails The Backers Are Left With No Way Out

A few years ago an enterprising programmer dug through Kickstarter's data to figure out how many failed projects there really were. Thanks to a trick in the.. Read more

Business Insider

A programmer wrote scripts to secretly automate a lot of his job — and email his wife and make a latte

There's a hilarious project that's gone viral on GitHub that consists of a bunch of software scripts that automate all sorts of crazy things. Read more

The Bests

The Best-Looking Video Game Consoles Of All Time

You silly fanboys. All these years arguing over things you thought were important, like specs, and libraries, and exclusives, and controllers, wasted. Not once have you considered the most crucial thing about a video game console: how good it looks. Read more

The Founder Institute

The Founder Institute

FI.co: How to Build an MVP as a Non-Technical Founder

The Founder Institute hosts webinars every month so that we can help entrepreneurs on any stage succeed. These webinars discuss a wide range of topics, bestowing global entrepreneurs with invaluabl... Read more

TechCrunch

TechCrunch

Google’s New “About Me” Page Lets You Control What Personal Info Others Can See

Worried that Google has too much of your personal data, thanks to the way it has pried into your life over the years as you steadily adopted more of its.. Read more