Results 1 to 7 of 7

Thread: Clarification about Controller 'refs'

  1. #1
    Sencha Premium Member
    Join Date
    Jul 2012
    Posts
    64

    Default Clarification about Controller 'refs'

    So we've started to use Controller 'refs' quite extensively -- but a thought ocurred to us and we began to question our understanding of this facility.

    As we understand it, the 'refs' feature is a handy shortcut that causes a controller to create a getter() method based on a ComponentQuery syntax.

    Our confusion surrounds how the Controller decides which compnent to select where there may be more than one to choose from. Quick example.

    Say we have a top level window with a textfield, and a button. We create a controller, and add a ref to the textfield. something like:

    Code:
        refs: [
            {
                ref: 'input',
                selector: 'window > textfield#input'
            }
        ],
    We create a custom action linked to the button.click that needs to extract the textfield and process it.

    Now say we instatiate two (2) of these top level windows. If in our controller's button.click action, we do something like:

    Code:
    var input = this.getInput();
    The question -- how does the controller correctly resolve ComponentQuery()? Or perhaps my question should be DOES the controller correctly resolve the selector at all?

    In case you ask why we care -- say for example each top level window had some private state stored in proprties associated with the window container. We'd need to be sure the textinput was processed in the correct context.

  2. #2
    Sencha User Phil.Strong's Avatar
    Join Date
    Mar 2007
    Location
    Olney, MD
    Posts
    1,953

    Default

    I believe that this will get you all 3 textfields. The easiest way to find out is to test it!

    Good question btw
    Phil Strong
    @philstrong

  3. #3
    Sencha Premium Member
    Join Date
    Jul 2012
    Posts
    64

    Default

    Hmm. When you save 3 -- can I assume you meant 2 (referring to my example, I proposed two top level windows).

    As for testing -- that is the head scratcher. We've been using the ref system extensively -- and so far it seems to always return the correct item. But it has slowly begun to dawn on us that perhaps it's just good luck (rather than our brilliant design ) that explains our success.

    We were looking for some sort of authoritative answer as to what/how the controller base class handles creating getters() and routing the events. Are we guaranteed with refs that they will always provide the correct result? OR is it simply doing something like Ext.ComponentQuery() (or Ext.getCmp()) ?

    Testing would seem to not be enough in this case as there'd be no way to ensure every code path was testing without understanding the implementation thoroughly. We're still new to Extjs and SA and was hoping for someone could provide something concrete.

    Thanks

  4. #4
    Sencha Premium Member
    Join Date
    Oct 2008
    Posts
    41

    Default

    It use Ext.ComponentQuery.query(ref)[0] , as you can see, if the component query return more than one component, it return the first item in the array...............

    In the case of controller action, create a listener for the event, for all the component that match the query expression

  5. #5
    Sencha Premium Member
    Join Date
    Jul 2012
    Posts
    64

    Default refs have very limited usefulness

    I hope no one takes offense at this comment -- but in my view controller refs have very limited usefulness. On the surface, they seemed to be a great way to enforce DRY (don't repeat yourself) principles, and reduce the linkage between code and presentation. But in practice, they have very limited practical application.

    For any new users who stumble upon 'refs' I think it's worth understanding they MUST refer to a singleton element. One which does not re-ocurr anywhere within the app. Perhaps something like page header or footer elements are a suitable use of refs. But they are not suitable for components that occur within a top-level windows and panels -- unless they are also modal.

    Refs also do not work as 'controlQuery' fields for controller actions (which is where they could have really been a big win).

    We have started to eliminate our use of controller 'refs'

    NOTE: I recognize the difficulty in trying to address these comments, and am not asking Sencha to change anything. These comments are only meant to share our experiences with others who are coming up to speed on extjs & SA.

  6. #6
    Sencha User Phil.Strong's Avatar
    Join Date
    Mar 2007
    Location
    Olney, MD
    Posts
    1,953

    Default

    I think what Jim writes here is mostly fair. Refs are meant to be a way to reference an item. If you want to add listeners to all of your buttons then you would use a query not a ref. It's also more verbose this way assuming you can read CQ.
    Phil Strong
    @philstrong

  7. #7
    Sencha Premium Member
    Join Date
    Oct 2012
    Posts
    18

    Default

    Dear Jim,

    thanks for this interesting post. When I first went through the controllers documentation and started experimenting with it, I encountered the same question. I'm adding my example and my current solution - just for knowledge sharing reasons. Any better implementation suggestions are welcome.

    Suppose you want to implement a window, having a button and two panels with different colors. Whenever you tap the button, the colors flip, in this example one panel from green to red, and the other panel from red to green, respectively. The implementation uses a subclass flippanel and holds in the mainpanel two instances of it. In the controller we need to call the flipColor function for both instances.

    Code:
    // Simple experiment to understand refs
    
    Ext.define('Test.view.FlipPanel', {
        extend: 'Ext.Panel',
        xtype: 'flippanel',
        
        config: {
            color: 0,
            style: 'background: green',
        },
        
        flipColor: function () {
            if (this.getColor() == 0) {this.setStyle('background: red'); this.setColor(1);}
            else {this.setStyle('background: green'); this.setColor(0);}
        },
        
        initialize: function () {
            if (this.getColor() == 1) this.setStyle('background: red');
            if (this.getColor() > 1) this.setColor(0); // in case of misuse
        }
        
    });
    
    
    Ext.define('Test.view.Start', {
        extend: 'Ext.Panel',
        
        config: {
            layout: 'vbox',
            items: [
                {
                xtype: 'panel',
                style: 'background: white',
                flex: 1,
                items: [
                    {
                    xtype: 'button',
                    text: 'tap me',
                    centered: true
                    }
                ]
                },
                {
                xtype: 'flippanel',
                color: 0,
                flex: 1
                },
                {
                xtype: 'flippanel',
                color: 1,
                flex: 2
                }
            ]
        }
        
    });
    
    // Controller looks like ...
    
    
    Ext.define('Test.controller.Control', {
        extend: 'Ext.app.Controller',
        
        config: {
            control: {
                'button': {
                    tap: 'colorChangeRequest'
                }
            }
        },
        
        colorChangeRequest: function() {
            var flippanels = Ext.ComponentQuery.query('flippanel');
            Ext.Array.forEach(flippanels, function(obj) {obj.flipColor();});
        }
        
    });

    My first idea was: let refs always return an array ... but I'm sure Sencha has reasons for not implementing it this way?

    -Niko

Posting Permissions

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