Results 1 to 6 of 6

Thread: An inheritance problem

  1. #1
    Ext JS Premium Member
    Join Date
    Aug 2011
    Posts
    26

    Question Answered: An inheritance problem

    I'm running the demo code found here:

    http://docs.sencha.com/ext-js/4-0/#/...n_architecture

    I'm trying to extend this code to add and delete users. To do this, I added a "delete" button to the Edit view. This works.

    To add a new user I need a window that looks exactly like the old Edit view (without the delete button). So I added this. That works too. But now I have duplicated code in the Add and Edit views which I want to refactor. I want Edit to inherit from Add with the addition of a delete button. So I tried this:

    Code:
    Ext.define('MyApp.view.user.Edit', {  extend: 'MyApp.view.user.Add',
      alias : 'widget.useredit',
    
    
      title : 'Edit User',
    
    
      initComponent: function() {
        this.callParent(arguments);
        this.buttons.push({ text: 'Delete', action: 'delete' })
      }
    });
    This fails with the following error:

    TypeError: Result of expression 'me.buttons' [null] is not an object.

    The reason this happens is that the call to this.callParent(arguments) in MyApp.view.user.Add sets the buttons property to null, i.e. if I put this at the end of MyApp.view.user.Add.initComponent:

    Code:
        console.log(this.buttons);
        this.callParent(arguments);
        console.log(this.buttons);
    The output is:

    [Object, Object]
    null

    So... what is the right way to do this?

  2. Implementing an imitation of formBind should be easy enough:

    Code:
    Ext.define('MyApp.view.user.Add', {
        extend: 'Ext.window.Window',
    
        layout: 'fit',
    
        initComponent: function() {
            this.buttons = this.createButtonsConfig();
    
            this.items = [{
                border: false,
                xtype: 'form',
    
                items: [
                    ... // your fields go here
                ],
    
                listeners: {
                    scope: this,
                    validitychange: function(form, valid) {
                        Ext.each(this.query('[formBind]'), function(button) {
                            button.setDisabled(!valid);
                        });
                    }
                }
            }];
    
            this.callParent();
        },
    
        createButtonsConfig: function() {
            return [
                {text: 'Add', formBind: true},
                {text: 'Edit', formBind: true}
            ];
        }
    });

  3. #2
    Ext JS Premium Member
    Join Date
    Aug 2011
    Posts
    26

    Default

    I think this might actually be related to this bug:

    http://www.sencha.com/forum/showthre...-on-form-reset

    The bug in question is about formBind not working, but the underlying cause could be the same, namely, the initComponent method nuking the list of buttons when it shouldn't be.

    Just sayin'


  4. #3
    Sencha Premium Member skirtle's Avatar
    Join Date
    Oct 2010
    Location
    UK
    Posts
    3,791
    Answers
    585

    Default

    I think your diagnosis is slightly off. I believe the this.buttons array is processed during initComponent(), so pushing an extra config on the end of the array after you call initComponent() won't have any effect anyway. Setting it to null is just housekeeping.

    You have a number of options to get this working. You could do some painful stuff involving retrieving the toolbar and inserting an extra item. If you don't have access to the code for the superclass then this might be your only option. However, it sounds like you do have access to the code for both classes so there's a much more elegant way to do it using a template method to create the config.

    I've simplified the code a little but the principle is hopefully clear.

    Code:
    Ext.define('MyApp.view.user.Add', {
        extend: 'Ext.window.Window',
    
        initComponent: function() {
            this.buttons = this.createButtonsConfig();
            this.callParent();
        },
    
        createButtonsConfig: function() {
            return [
                {text: 'Add'},
                {text: 'Edit'}
            ];
        }
    });
    
    Ext.define('MyApp.view.user.Edit', {
        extend: 'MyApp.view.user.Add',
    
        createButtonsConfig: function() {
            var buttons = this.callParent();
            buttons.push({text: 'Delete'});
    
            return buttons;
        }
    });

  5. #4
    Ext JS Premium Member
    Join Date
    Aug 2011
    Posts
    26

    Default

    Thanks!

    One more followup question: I want to bind my submit button to the form so that it is inactive when the form fields are invalid. It's easy to do this with an Ext.form.Panel (just specify "formBind: true" in the submit button*) but is there an easy way to do the same thing when your form and buttons are inside an Ext.window.Window?

    I tried the obvious thing of extending Ext.form.Panel instead of Ext.window.Window to make my edit view, but that didn't work. I also tried the less obvious thing of manually sticking my button in the form's _boundItems property. That didn't work either.

    ---

    *There is a known bug that prevents this from working, but there's also a workaround.

  6. #5
    Sencha Premium Member skirtle's Avatar
    Join Date
    Oct 2010
    Location
    UK
    Posts
    3,791
    Answers
    585

    Default

    Implementing an imitation of formBind should be easy enough:

    Code:
    Ext.define('MyApp.view.user.Add', {
        extend: 'Ext.window.Window',
    
        layout: 'fit',
    
        initComponent: function() {
            this.buttons = this.createButtonsConfig();
    
            this.items = [{
                border: false,
                xtype: 'form',
    
                items: [
                    ... // your fields go here
                ],
    
                listeners: {
                    scope: this,
                    validitychange: function(form, valid) {
                        Ext.each(this.query('[formBind]'), function(button) {
                            button.setDisabled(!valid);
                        });
                    }
                }
            }];
    
            this.callParent();
        },
    
        createButtonsConfig: function() {
            return [
                {text: 'Add', formBind: true},
                {text: 'Edit', formBind: true}
            ];
        }
    });

  7. #6
    Ext JS Premium Member
    Join Date
    Aug 2011
    Posts
    26

    Default

    That worked. That "listeneres" incantation is apparently what I needed. Thanks!

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •