Tag Archives: sencha

The State of ExtJS

I’ve been a big fan of Sencha’s ExtJS since I started using it several years ago. When I was first exposed to the framework in its v2.0 days, it was a breath of fresh air compared to anything else out there. It had a well-documented, powerful framework and a comprehensive set of widgets. The grid widget alone scratched enough itches that the rest of the framework was gravy.

I haven’t been able to use it on any projects, though, for a couple years, but I have tried to stay up to date on the releases. Unfortunately for Sencha, in the intervening years, the internet has started to catch up and I’ve been taking a much more critical eye to ExtJS. There are still several good parts to ExtJS, but there are also a lot of bad things that will limit its suitability for any future projects.

The Good Parts

  • The Documentation : The guys at Sencha have continued to do an excellent job at creating documentation for ExtJS. As a Java developer, I found the API documentation pretty similar to JavaDoc, and thus instantly appealing. The documentation has continued to improve and now includes extensive sample code and even videos. This is an area where ExtJS leads the industry.
  • The MVC Framework : While there is significant competition in the JavaScript MVC space, most of the competition is still in catch-up mode. ExtJS still has one of the most well thought out and comprehensive MVC frameworks available. Similar to Rails, it even provides a consistent project configuration and directory hierarchy to improve the maintainability of ExtJS applications.
  • The Support : The support forums for ExtJS are first rate. Questions get answered quickly and the Sencha team does a good job staying on top of them. Sencha also offers commercial support and training, which is critical for enterprises where developer skillsets are hit and miss.
  • The Ecosystem : Sencha has built a comprehensive developer ecosystem around ExtJS. This includes command line tools (Sencha Command), design tools (Sencha Architect), and Eclipse plugin, charting and a mobile framework (Sencha Touch). Yes, these are commercial offerings, but from the perspective of the enterprise users they are targeting, Sencha provides a one-stop-shop for building rich JavaScript RIA applications.

The Bad Parts

  • Outdated Theme : This is the biggest area where Sencha has been caught with their pants down. When I started using ExtJS, everyone was trying to web-enable desktop applications. Sencha provided the typical desktop look-and-feel in HTML widgets which made it perfect for implementing intranet applications to ween users off of Visual Basic. Today, the objectives have completely flipped. Even Microsoft is working to desktop-enable web applications. Clean, modern web applications have set the standard for user interfaces and the theme for ExtJS still looks like Visual Basic for the web.
  • (Un)Resonsive Design : The ExtJS library is designed for desktop browsers. But the world is moving to a post-PC world with BYOD Tablets and Smartphones. Just try viewing the Feed Viewer demo application on an iPad to understand how badly ExtJS is being left behind in the area of responsive design. Yes, Sencha has a mobile framework, but we’re moving to a world of responsive designs that we expect to scale satisfactorily to an device.
  • The Competition : While the ExtJS MVC framework is still at the top of the heap, the competition is climbing fast. Frameworks like EmberJS, AngularJS and Backbone continue to close the gap, and due to their open source nature, there is a good chance they will overtake ExtJS in the near future.
  • Monolithic vs Micro : ExtJS is a monolithic framework. It has an answer for every problem and you need to embrace the complete paradigm. Using ExtJS means you don’t want to play nice with others. The web world has swung the other direction towards micro frameworks, or pulling together only the small, best-of-breed libraries you need. JQuery is usually the base, and then you pile other things on top it like RequireJS for code structure, Twitter Bootstrap for the user interface and LESS or Compass for CSS.
  • Learning Curve : ExtJS is not a casual framework. Learning the framework requires a lot of work and it is not something you decide to use for a small project every now and then. You would pull your hair out going through perpetual ramp-up. In some ways, ExtJS has become the PowerBuilder of web development. It is an extremely powerful framework that people build careers around, but is way too complex for a casual user. The high learning curve can make it extremely difficult to staff a qualified team for a large project.
  • Bad Blood : I do not fall in to this camp, but it still amazes me to this day how much bad blood there is in the developer world over the ExtJS licensing fiasco from a few years ago. A lot of developers I know who are familiar with ExtJS will literally start frothing at the mouth if the name comes up.
  • Uncertainty : Sencha is still a VC-funded startup that is going to have to get bought by someone for the vultures to get their pound of flesh back. As the web evolves, it is going to be increasingly difficult for them to find a suitor. Would anyone still have as much enthusiasm for ExtJS if it were owned by SAP or Oracle?

The Sweet Spot

ExtJS really only has one sweet spot today: developing data-centric intranet applications that users will spend all day in front of. These are scenarios where you would have used a VB or WinForms application. Nothing comes close to ExtJS in solving this problem.

That sweet spot is shrinking. Users are expecting their work world to mimic their private worlds. They like the clean designs of Facebook, Twitter, Google+, etc… and are increasingly expecting even in house applications to function and look like what they’re accustomed to. ExtJS does not fit the bill for this future.

What to Do

If I were Sencha, I would be hiring some top UX talent and coming up with a cleaner, more internet ready theme for ExtJS while it still has a chance for relevancy. The theming framework also needs the equivalent of ThemeRoller and several pre-built, high-quality themes distributed with the framework. The theme also needs to be responsive. You can’t just steer people to Sencha Touch to solve the tablet problem.
If I was already invested in ExtJS, I wouldn’t change anything right away for existing applications but I would carefully think through using it for anything new. I would ensure I stayed current with the versions to ensure my teams could take advantage of the awesome MVC framework, but I would be keeping an eye to a future without ExtJS.
If I were building a new internet facing application, I wouldn’t touch ExtJS with a ten-foot pole. The outdated look-and-feel, and the difficulty in themeing it, is an absolute deal killer. I would start with a solid micro framework like AngularJS and layer it on top of Bootstrap and LESS.

I don’t want to be too harsh on the Sencha guys. I’ve met a lot of them, and I think they’re great and can absolutely rebound from their problems. But similar to an alcoholic, the first step is acknowledging you have a problem. And that problem for Sencha is that ExtJS is no longer ready for today’s internet. Sencha has to resolve this, because even if they only want to focus on enterprise intranets, that world is changing too.

Getting Touch-y

At the recent hackathon, I decided to use JQuery Mobile for my application instead of Sencha Touch. I hadn’t played with Sencha Touch for a while, and it isn’t a “casual user” friendly framework, so I was able to be productive on short notice with JQuery Mobile.

Now that Sencha Touch 2 has reached Release Candidate status, I decided to give it a try for another small side project I’ve wanted to do. I kept the backend the same, using NodeJS and Express, but took the time to dive in and learn Sencha Touch 2 at least enough to be productive.

First off, Sencha Touch 2 has really improved in the documentation area. The docs include a lot more examples, and I found the Jog with Friends sample to be the most useful. The API documentation is also much improved. Each of the classes contains sample code so you can quickly see how to use the features.

On the downside, the documentation isn’t 100% consist on how applications are created. For example, the Ext.Map sample uses the trimmed-down Ext.setup() versus the preferred Ext.application() syntax.

One of the best resources for learning the framework is the SenchaLearn Github repository. This has a lot of tutorial and sample applications. Drew Neil also has an excellent collection of sample applications on his repository. His Sencha-Touch-Boilerplate project gives you a great starting point for an application, making development a lot easier. I used this boilerplate for my application and it works great.

The biggest mental hurdle with Sencha Touch 2 was getting my head around how the MVC components interact. It all came together for me when the notion of refs and controls clicked. In a typical Java / Spring Framework application, URLs are mapped to a controller, which then determines the view to render. In a simple Sencha Touch 2 application, that doesn’t have to be the case, and that is what kept throwing me off.

In a Sencha Touch 2 application, you can specify routes that map URLs to controller actions, but that isn’t necessary in a small application. Instead, you load the Viewport with a view, and the controllers are event listeners around the actions in a view.

For example, here’s my app.js file:

Ext.application({
    name: 'Javamug',

    controllers: ['Main'],
    views: ['Main'],

    launch: function() {
        Ext.Viewport.add({
            xclass: 'Javamug.view.Main'
        });
    }
});

I’m loading up the Viewport with a specific view and that’s it. In this case, my Main view is TabPanel, and it loads up a bunch of tabs. Sencha Touch takes care of rendering the correct view when you click an icon on the tab, which is a nice time saver.

Here’s what the first page looks like:

>

In one of my views, I have two buttons which are defined like this:

{xtype: 'button', ui: 'green-round', text: 'Yes', id: 'attendButton'},
{xtype: 'button', ui: 'red-round', text: 'No', id: 'declineButton'}

Note I added an id attribute to them. This is what makes controllers easy to use. In my Controller, I define the refs and control properties to capture the events from these buttons and call some methods when they are tapped:

config: {
    refs: {
        attendButton: '#attendButton',
        declineButton: '#declineButton'
    },
    control: {
        '#attendButton': {
            tap: 'attendMeeting'
        },
        '#declineButton': {
            tap: 'declineMeeting'
        }
    }
}

The refs section is create some getters for my two buttons. Since I put an ID on the components, I can use that to map them to the friendly names in my controllers. The result is that inside the controller, I can call getAttendButton() and getDeclineButton() from my code to get access to the button directly without having to navigate some contorted hierarchy.

The control section works in a similar way. I’m using the ID of the components, which get mapped back to the components via the ComponentQuery class at runtime. Inside the braces for each button, I’m defining an event listener for the button’s tap event. In this case, tapping the button with ID of attendButton will call the attendMeeting() method in the controller.

Once I quit trying to forcibly shoehorn the controllers into the process, similar to how I would do in Java, and just let them be event handlers, life got easy. I’m still learning the ropes, and I know it is possible to specify URL routes inside the controllers, but I didn’t have a need to do that in my simple application.

The next hurdle was with the Ext.Map component. I wanted a tab which showed the location of our meeting in a Google Map. I beat myself over the head for a whole evening trying get this to work right. It was complicated by the examples not being consistent. The Jog with Friends, Kitchen Sink and Map Demo samples each do things differently. Complexity was compounded by the fact there is a bug with the Release Candidate with rendering maps on TabPanels.

In the end, I finally got it to work by creating the map in the initialize() method of the view and adding it to the Container manually. The code looks like this (after dealing with the bug):

Ext.define('Javamug.view.Map', {
    extend: 'Ext.Container',
    xtype: 'mapcard',
    
    requires: [
    	'Ext.Map'
    ],

    config: {
        iconCls: 'locate',
        title: 'Location',
        layout: 'fit',

        items: [
            {
                ui: 'light',
                docked: 'top',
                xtype: 'toolbar',
                title: 'Location'
            }
        ]
    },

    initialize: function() {

        this.callParent();

        var position = new google.maps.LatLng(32.9770421, -96.8270373);

        var infowindow = new google.maps.InfoWindow({
                content: 'Improving Enterprises
Addison, TX 75001' }); var map = Ext.create('Ext.Map',{ mapOptions : { zoom : 14, mapTypeId : google.maps.MapTypeId.ROADMAP, navigationControl: true, navigationControlOptions: { style: google.maps.NavigationControlStyle.DEFAULT } }, listeners: { maprender: function(comp, map) { var marker = new google.maps.Marker({ position: position, title : 'Improving Enterprises', map: map }); google.maps.event.addListener(marker, 'click', function() { infowindow.open(map, marker); }); } } }); map.setMapCenter(position); this.add(map); } });

The mapConfig section was a major pain too. Normally, you can specify a center property which contains the LatLong of where you want to center the map. Except it doesn’t work. My desired center kept popping up just out of view in the top left corner. I finally removed the property from the config and just manually called the setMapCenter() method of the Ext.Map component and that worked.

One thing I don’t like about Sencha Touch is how it handles pages which are mostly HTML text. Stuffing a bunch of HTML markup into the html config element isn’t an elegant solution. Fortunately, the Oreilly demo app has a good way of solving this. They create a new panel which takes a URL in the config and uses the initialize() method to load the content for the URL. The code looks like this:

Ext.define('Javamug.view.Meeting', {
    extend: 'Ext.Container',
    requires: ['Ext.Ajax'],

    config: {
        iconCls: 'calendar2',
        title: 'Meeting',
        styleHtmlContent: true,
        scrollable: 'vertical',
        url: 'current.html',
        items: [{
            ui: 'light',
            docked: 'top',
            xtype: 'toolbar',
            title: 'Java MUG'
        }]
    },

    initialize: function() {

         Ext.Ajax.request({
            url: this.config.url,
            success: function(rs) {
                this.setHtml(rs.responseText);
            },
            scope: this
        });
    }
});

Using this technique, I could use a Jade template in Express to create the “static” content rather than pack it all into the JavaScript view file.

Outside the complexity, there are two downsides to using Sencha Touch. First is theming. This blog post provided the most help in figuring out how theming works. Using the Bootstrap template above also make life a lot easier because it starts with the app.scss and config.rb in the right place and includes instructions in the README.md file on how to compile them.

The second downside is size: Sencha Touch is not a light-weight framework. My CSS, combined app-all.js and framework files came in around 700K for a simple application. I could trim things down by eliminating some of the includes on the theme, but that is still pretty large. By comparison, in my JQuery Mobile application, the framework files came in around 250K in size.

The tradeoff for the larger size is being able to use a sophisticated client-side MVC framework with great looking, and performing, components.

Sencha Touch 2 is a big win for me. I want to work on the file size, but now that I have a feel for the framework, I’m expecting my learning to pick up. I’ll hopefully get a chance to give a whirl on a larger application soon.

The Sencha guys have really knocked it out of the park with Sencha Touch 2. It is, without a doubt, the most sophisticated and polished mobile JavaScript framework out there right now.

Sencha Touch Initialization

I’ve finally had the chance to dig in to Sencha Touch. I was really impressed with the framework from what I saw at SenchaCon last year, but I had been too busy with regular web development to get very far with it. That all changed now that I’m working on a mobile website for work.

Sencha Touch is very well documented, and has a boatload of examples. Unfortunately, some of the examples don’t necessarily promote best practices. The first place I ran in to problems was on setting up an Application.

If you look at the documentation and the examples, there are three ways to initialize a new Touch application:

  1. Ext.setup({...})
  2. Ext.ApplicationManager.registerApplication({...})
  3. new Ext.Application({...})

Most all the examples use the first method, including the more complicated GeoCongress app. Unfortunately, this isn’t the best method for real-world applications. It is designed for quickly setting up a Viewport and rendering a container. Yes, some of the more complicated samples use this technique, but doing so costs you a lot of the free stuff that come with using one of the other two approaches.

The second approach is used in the Kiva and Twitter examples. The end result will do the same as option #1, except you’ll have an Ext.Application object to work with. Ext.Application is one of those secret sauce objects that take care of a lot of the common setup tasks for you. When you initialize an Ext.Application, the object automatically creates a set of namespaces for your views, stores, models and controllers, prefixed by the application name. It also provides support for a load mask and sets up an Ext.History object for the application. Finally, it integrates with the Ext.Dispatcher object for handling custom routing of requests and registers the application with the ApplicationManager.

The third approach is nearly exactly the same as the second option, except you are directly instantiating an Ext.Application versus delegating to the Ext.ApplicationManager to create that application. This means that the Application will not be registered with the ApplicationManager. In practical terms, this really doesn’t matter. The Ext.ApplicationManager permits you to register multiple logical applications for a single physical Sencha Touch site, which is not something I see as being necessary.

While trying to sort this all out the first time through, I put out a query on Twitter to see what others thought. I was pretty much between options #1 and #2, but the awesome James Pierce (@jamespierce) from the Sencha team chimed in and recommended option #3 as the best going-forward approach.