Click here to Skip to main content
15,881,424 members
Articles / Hosted Services / ExtJS
Tip/Trick

Ext JS MVVM Tricks: Part 1. Self Binding

Rate me:
Please Sign up or sign in to vote.
5.00/5 (3 votes)
30 Mar 2017CPOL4 min read 16.5K  
In this tip, you will learn how to create a component with configuration properties and bind to them using MVVM.

Introduction

This tip is created for advanced users who want to squeeze a little bit more juice from MVVM in Ext JS, for those who have an intuitive knowledge that some things could be done better.

In this part, we are going to review a self binding trick. What is it? Briefly, it is a data binding within a custom component.

This is related to the encapsulation principle. When you create your own component with its configuration properties (configs), you wish them to be bound to some of the inner components. For example, a projectName config to be displayed in a label, or a locked flag to affect the availability of some fields.

Let's explore the ways to do this.

Background

Here is the official MVVM guide from Sencha: View Models & Binding.

In these examples, Sencha uses one ViewModel for everything. And binds the data in a single view. This is acceptable for a small project but this definitely will be a problem in a big one. Someday, you'll come up with creating independent reusable components and using the benefits of MVVM at the same time.

Example

Take a look at this example. Here, we want to create a reusable component, a grid with users. The 'Remove' button contains the name of a selected user. The grid may be locked for changes with a configuration property. Let's call it readOnly. In this example, we'll do it with the 'Set Read only' button outside of the component. We also want to bind to grid's selection in the outer container.

Image 1

Our Goals

  • Use the configuration properties to change the component's state
  • Use the benefits of MVVM. No handlers, just data bindings
  • Be able to use the grid in a container with its own ViewModel or without

Problems

If we start, we would face some limitations of the framework:

  • A component cannot make a bind between its configuration properties and the inner components.
  • An outer component cannot bind to the component's published properties if the inner component has a ViewModel (ticket #EXTJS-15503).

They look strange for me so I've decided to make a fix. It's called Ext.vmx.mixin.Bindable and it solves these problems.

Using the Code

So with this fix, we can write a component we want. Take a look at this piece of code.

JavaScript
/**
A reusable users grid
*/
Ext.define('Fiddle.view.UsersGrid', {
    extend: 'Ext.grid.Panel',
    xtype: 'usersgrid',
    
    viewModel: {
        
    },
    
    config: {
        readOnly: false
    },
    
    publishes: ['readOnly'],
    
    tbar: [{
        text: 'Add',
        itemId: 'addButton',
        bind: {
            disabled: '{readOnly}'
        }
    }, {
        text: 'Remove',
        itemId: 'removeButton',
        bind: {
            disabled: '{readOnly}',
            text: 'Remove {selection.name}'
        }
    }],
    
    columns: [{
        dataIndex: 'id',
        header: 'id'
    }, {
        dataIndex: 'name',
        header: 'name'
    }]
});

Looks pretty elegant, right? Here is what we've done:

  • Defined an empty viewModel
  • Defined a readOnly config
  • Marked it as a published in the publishes section
  • Created data bindings to the readOnly config
  • Created data binding to a selection config. It was also marked as a published by Ext.grid.Panel

Benefits

So what's good with it? There is something I personally like:

  • The component is now more independent. You can use it within a container which has a ViewModel or doesn't. There is no difference now.
  • You don't need to define anything in a ViewModel. This is automatically done with the publishes section.
  • You are free of creating any handlers for your configuration properties. Everything is handled by the MVVM engine. So the code becomes smaller.

I've been using this extension in my projects for about 2 years and I haven't had any issues. It is backward compatible so you can use it in your projects and it won't break anything.

Don't forget to include 'Ext.vmx.mixin.Bindable' somewhere in the requires section of your application.

Cons

One thing we have to keep in mind using this approach. "Don't nest data objects more deeply than necessary" - a recommendation from Sencha. Other way, we may face a performance issue. For example, I'm not going to create a recursive comment tree where each comment is displayed in a component with a ViewModel. But I had no performance slowdown with 3-4 levels ViewModel hierarchy.

Source

All right, if you like it, please check out an online demo at Sencha Fiddle:

and the source code at GitHub:

To Be Continued

In the second part, we'll talk about an even stronger component isolation speaking in terms of Ext JS MVVM. At the moment, you may still mess around with a ViewModel hierarchy, with data names, should they be unique, should you use references and why do they work in one direction only, etc. So in the next part, we'll talk about how to make MVVM more predictable in a growing project.

Updates

  • Fixed missing image

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer
Russian Federation Russian Federation
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
-- There are no messages in this forum --