The account window

The account view is a window that contains several subcomponents (such as login, register, and past orders). Let's take a look at the lengthy, but straightforward code for it:

// app/view/account/Account.js
Ext.define('Alcohology.view.account.Account', {
    extend: 'Ext.Window',
    xtype: 'account',
    layout: 'fit',
    controller: 'account',
    modal: true,
    resizable: false,
    header: false,
    onEsc: Ext.emptyFn,
    width: 800,
    autoHeight: true,
    frame: true,
    items: [
        {
            xtype: 'container',
            layout: 'column',
            items: [
                { xtype: 'login', title: 'Login', columnWidth: 0.5 },
                { xtype: 'register', title: 'Register', columnWidth: 0.5 }
            ],
            bind: { hidden: '{currentUser}' }
        },
        {
            xtype: 'container',
            layout: 'column',
            items: [
                { xtype: 'register', title: 'Register', columnWidth: 0.5 },
                {
                    xtype: 'panel',  title: 'Past Orders',
                    columnWidth: 0.5, items: [
                        { xtype: 'pastorders', bind: '{orders}' }
                    ]
                }
            ],
            bind: { hidden: '{!currentUser}' }
        }
    ],
    bbar: [
        '->',
        { text: 'Close', itemId: 'close' },
        {
            text: 'Login/Register', itemId: 'loginRegister',
            bind: { hidden: '{currentUser}' }
        }
    ]
});

We've got two panels here, both set to use a column layout. One contains the login and registration forms and is shown when the user is logged out. Another shows the registration form repurposed as a way to let the user edit their profile details and the past orders. The second panel is only shown when the user is logged in.

The hiding and showing of components in the account window is accomplished by binding the hidden config to currentUser at the top-level main view model. Ext JS converts the user object to a "truthy" value, that is, either true or false. This is used to set the component's visibility.

Next, we have the login component, which is just an Ext.FormPanel with the relevant fields along with a little bit of explanatory text, as shown in the following code:

// app/view/account/Login.js
Ext.define('Alcohology.view.account.Login', {
    extend: 'Ext.FormPanel',
    xtype: 'login',
    items: [
        { 
            xtype: 'fieldset', margin: 10, padding: 10,
            defaults: { xtype: 'textfield', width: '100%' },
            items: [
                { fieldLabel: 'Email', bind: '{email}', vtype: 'email' },
                { fieldLabel: 'Password', inputType: 'password' }
            ]
        },
        {
            xtype: 'container',
            padding: 10,
            html: 'If you've already got an Alcohology account,please enter your login details above. If not, please complete the registration form and join us!'
        }
    ]
});

Then, we have the register component, another form containing the fields that a user must complete in order to sign up:

// app/view/account/Register.js
Ext.define('Alcohology.view.account.Register', {
    extend: 'Ext.FormPanel',
    xtype: 'register',
    defaultType: 'textfield',
    items: [
        {
            xtype: 'fieldset', margin: 10, padding: 10,
            defaults: { xtype: 'textfield', width: '100%' },
            items: [
                { fieldLabel: 'Email', bind: '{email}', vtype: 'email' },
                { fieldLabel: 'Password', inputType: 'password' }
            ]
        },
        {
            xtype: 'fieldset', margin: 10, padding: 10,
            defaults: { xtype: 'textfield', width: '100%' },
            items: [
                { fieldLabel: 'House Number' },
                { fieldLabel: 'Street' },
                { fieldLabel: 'Town' },
                { fieldLabel: 'County' },
                { fieldLabel: 'Postcode' }
            ]
        }
    ]
});

The final piece of the account user interface is the past orders component:

// app/view/account/PastOrders.js
Ext.define('Alcohology.view.account.PastOrders', {
    extend: 'Ext.DataView',
    xtype: 'pastorders',
    tpl: new Ext.XTemplate('<tpl for="."><div class="past-order">',
        '<h3>Ordered on {date:date("m F Y")}</h3>',
        '<ul><tpl for="items">{name} x {quantity}</tpl></ul>',
        '<p>Total: &pound;{total}</p></div></tpl>'),
    itemSelector: '.fake',
    emptyText: 'No Previous Orders.'
});

Here, we use DataView with itemTpl configured to output all of the orders as well as loop through the items within this order. As none of the past orders are clickable, there's no detail view for orders to click on to. Therefore, we need to specify a fake itemSelector. Binding this component's store to the orders store on the view model was performed in the containing account window.

Finally, we have a simple view controller to handle interactions with the account window, as shown in the following code:

// app/view/account/AccountController.js
Ext.define('Alcohology.view.account.AccountController', {
    extend: 'Ext.app.ViewController',
    alias: 'controller.account',
    listen: {
        component: {
            '#close': { click: 'onAccountClose' },
            '#loginRegister': { click: 'onLoginRegister' }
        }
    },

    onAccountClose: function(btn) {
        this.getView().hide();
    },

    onLoginRegister: function() {
        this.getViewModel().set('currentUser', {
            email: this.getViewModel().get('email')
        });

        this.getView().hide();
    }
});

This is standard stuff in onAccountClose, but in onLoginRegister, we perform a very naïve login action in which the currentUser gets set to an object with the e-mail address that the user entered for login or registration. As previously discussed, we're bypassing a full authentication system for simplicity, but this demonstrates the general idea, that is, perform an action that ends up with a user being set on the inherited view model. Once again, you'll see that we don't have a separate account view model as everything's passed up and down to the one that's defined on the main view.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset