Ext JS 5.1 Upgrade Guide

Introduction

With this release of Ext JS, we have worked hard to minimize the impact of changes on existing code, but in some situations this was not completely achievable. This guide walks through the most important changes and their potential impact on Ext JS 5.0 applications.

Packaging

We have removed the top-level “ext*.js” files from the distribution. These files were of limited use in Ext JS 5 and were only preserved for testing and debugging the examples using the dynamic loader. Because Ext JS 5 is a Sencha Cmd Package, its build content has always been in the “build” sub-folder, but the presence of these stubs in the root has generally created confusion for those familiar with previous releases.

You can run the examples in their built, optimized form from the “build/examples” folder.

To restore these stubs, you can run this command from the root folder of the extracted archive:

sencha ant bootstrap

Unification of Ext.util.Observable and Ext.mixin.Observable APIs

As mentioned in What’s New in Ext JS 5.1 , Ext JS 5.1 still has two Observable classes (Ext.mixin.Observable, and Ext.util.Observable), but their API differences have been eliminated. There is only one exception: Ext.mixin.Observable calls initConfig in its constructor whereas Ext.util.Observable uses the legacy Ext.apply approach to copy config object properties onto the instance. We recommend that applications use Ext.mixin.Observable going forward, but we will continue to support Ext.util.Observable for the foreseeable future since many classes internal to the framework and in user code depend upon its behavior.

Priority Ordering of Listeners

In the past the two Observables offered two different approaches to sorting listeners that needed to be run in a specific order. Ext.util.Observable used a numeric “priority” option to sort the listeners, while Ext.mixin.Observable used the “order” option which only had 3 possible values - “before”, “after”, and “current” (the default). Since “priority is the more flexible of the two, we are standardizing on it going forward, but the “order” option is still supported for compatibility reasons. Along with this change we have deprecated several convenience methods for adding a listener with a particular order:

  • addBeforeListener
  • addAfterListener
  • removeBeforeListener
  • removeAfterListener
  • onBefore
  • onAfter
  • unBefore
  • unAfter

API Unification

As part of the API unification process, each Observable class gains some features that were previously only available in the other Observable.

Ext.util.Observable gains the following features:

  • Auto-managed listeners - When calling on(), if a scope is provided, and that scope is an Observable instance, the listener will automatically become a “managed” listener. This means simply that when the scope object is destroyed, the listener will automatically be removed. This eliminates the need to use the mon() method in a majority of cases since the managing observable and the scope are typically the same object.

  • The fireAction method - Fires the specified event with the passed parameters and executes a function

  • The “order” option

  • The “args” option

Ext.mixin.Observable gains the following features

  • Class-level observability - allows entire classes of objects to be observed via the static observe() method

  • The “priority” event option

Plugin Authoring

In Ext JS 5.0, component plugins are automatically destroyed when the component is destroyed. This safety enhancement ensures that all plugins are cleaned up with their component but this can conflict with plugins written for previous versions of the framework have their own handling of component destroy. This is more prominent in Ext JS 5.1 due to the above merging of Observables and how listeners are auto-managed. The resolution is to remove any listeners for “destroy” events and instead rely on the destroy method being called by the component.

Two-Way Binding To Formulas

Prior to Ext JS 5.1, a two-way binding to a formula would not always write the value back as expected. Consider the following fiddle :

The ViewModel has a formula:

Ext.define('App.view.FooModel', {
    extend: 'Ext.app.ViewModel',
    alias: 'viewmodel.foo',

    formulas: {
        x2: {
            get: function (getter) {
                return getter('x') * 2;
            },

            set: function (value) {
                this.set('x', value / 2);
            }
        }
    }
});

The “x2” property in the above ViewModel is defined as “twice the value of ‘x’”. The view that is created has a child component with its own ViewModel:

Ext.define('App.view.Foo', {
    extend: 'Ext.panel.Panel',

    viewModel: {
        type: 'foo',
        data: {
            x: 10
        }
    },        

    bind: {
        title: 'Formula: {x2} = 2 * {x}'
    },

    items: [{
        xtype: 'numberfield',
        viewModel: {
            data: {
                label: 'Something'
            }
        },

        bind: {
            value: '{x2}',
            fieldLabel: '{label}'
        }
    }]
});

In this contrived example, we have two components each with their own ViewModel. Initially, the value of x was delivered to the formula and then x2 was delivered to the numberfield. When the number was increased, however, the value of x2 was simply written to the child’s ViewModel.

This behavior is consistent with the fact that ViewModel data is based on the JavaScript prototype chain, but was at odds with the goal of formulas. In Ext JS 5.1, writes to a formula will properly “climb” to the ViewModel with the formula defined and perform the set at that level.

Container move Event

The Ext.container.Container move event to indicate that a child component has had the index moved has been renamed to childmove . This resolves the conflict between this event and the Ext.Component move event.

ComboBox select Event

The Ext.form.field.ComboBox select event had an inconsistency where the records parameter would be passed as a single record in some cases or an array of records in others. This has now been corrected. The default behavior is to provide a array of records only when using multiSelect:true . The documentation for the event has been updated to reflect this.

Ext.FocusManager Removed

Due to conflicts with built-in focus treatment introduced in Ext JS 5.0.1, Ext.FocusManager has been removed.

For more details regarding accessibility, focus, and keyboard navigation improvements, see the Accessibility Guide .

Ext.menu.MenuManager no longer registers all Menus within your application. To access Menus in a global manner use Ext.ComponentQuery.

Charts

The axis rangechange event listener signature changed to include a missing parameter: the axis itself, which is now the first parameter, e.g.:

listeners: {
    rangechange: function (axis, range) {
        ...

SQL Proxy

The Ext.data.proxy.Sql class has been removed for Ext JS 5.1 but will be restored in a future release. This class was not planned to be in Ext JS 5.0 but was accidentally included during the merge of Sencha Touch and Ext JS data packages. Apologies for the inconvenience.

Last updated