Gelmiş geçmiş en büyük porno sitemiz olan 2pe de her zaman en kaliteli pornoları sunmayı hedefledik. Diğer video sitemiz olan vuam da ise hd porno ağırlıklı çalışmalara başladık.

  1. #1
    Sencha User
    Join Date
    Jan 2012
    Posts
    17
    Answers
    1
    Vote Rating
    0
    mminnie is on a distinguished road

      0  

    Default Answered: Best Practice for Handling Events in Subcomponents

    Answered: Best Practice for Handling Events in Subcomponents


    I want to once a gain thank the developers and contributors to ExtJS. There is much great documentation on the framework and many great forum posts, but I do see some (including some ExtJS 3.x experienced users) taking a bit to grasp the MVC of ExtJS 4.x. I think my question is fairly simple, but I didn't find a forum post or other documentation that answered my question. This may just be that the MVC structure of 4.x hasn't had time to generate as big of a knowledge base as earlier versions.

    I see many ways to handle events, but I'm interested in what is the best ExtJS 4.x MVC way to handle the events of a view. I have a user grid panel that is contained in a tab panel. I want to handle a double click on the user record in the grid to open up another tab for that specified user. My question is: Is the BEST PLACE in the ExtJS MVC design to "bubble-up" the grid itemdblclick event (or any other event from a view controlled by a controller) to the controller (User controller in my case)?

    UserList.jpg

    Code:
    Ext.define('LB.controller.Users', {
        extend: 'Ext.app.Controller',
    
        views: ['user.List','user.Tabs'],
        stores: ['Users'],
        models: ['User'],
        init: function() {
            this.control({
                'userlist *': {
                    itemdblclick: function(dataview, record, item, index, e) {
                        // Is this where YOU would put the handling of a itemdblclick for the grid?
                        console.log(record.get('username')+ ' was double clicked.');
                   }
                }  
            })
        }
    });
    Code:
    Ext.define('LB.view.user.Tabs' ,{
        extend: 'Ext.tab.Panel',
        alias : 'widget.usertabs',
        resizeTabs: true,
        enableTabScroll: true,
        defaults: {
            autoScroll:true
        },
        items: [{
            title: 'User List',
            items: [{
                xtype:'userlist',
                id: 'userlist'
            }],
            closable: false
    
    
        }]
    });
    Code:
    Ext.define('LB.view.Viewport', {
        extend: 'Ext.Viewport',
        layout: 'fit',
        
        initComponent: function() {
            this.items = {
                items: [{
                    xtype: 'usertabs'
                }]
            
            };
            
            this.callParent();
        }
    });

  2. Personally I wouldn't use an itemId without putting it in the context of an owner container. I also try to avoid control queries that don't include a custom xtype. So assuming the grid doesn't have its own alias the selector might be something like 'userlist #gridPanel'.

    A couple of other things I would change...

    You should avoid using static ids, e.g. id: 'userlist'.

    Though it's difficult to be sure, it looks like your code might be suffering from excessive panel nesting. For example, here:

    Code:
    items: [{
        title: 'User List',
        items: [{
            xtype:'userlist',
            id: 'userlist'
        }],
        closable: false
    }]
    Why not just this?

    Code:
    items: [{
        closable: false,
        title: 'User List',
        xtype: 'userlist'
    }]
    Implicit in the selector in your original question is that your grid is wrapped in a yet another panel with xtype userlist. From the screenshot it isn't clear why. Shouldn't userlist be the grid?

  3. #2
    Sencha User
    Join Date
    Feb 2011
    Posts
    35
    Answers
    2
    Vote Rating
    0
    nkezhaya is on a distinguished road

      0  

    Default


    Absolutely. All of that logic should be in the controller, but you should use "itemId", or a more specific selector.

    This is a better way to do it:

    Code:
    Ext.define('Controller', {
      extend: 'Ext.app.Controller',
    
      refs: [
        // refs here
      ],
    
      init: function() {
        this.control({
          '#gridPanel': {
             itemdblclick: this.onGridPanelItemDblClick
          }
        });
      },
    
      onGridPanelItemDblClick: function() {
        // code here
      }
    });
    You shouldn't actually write functions in the controller's initialization. That can get hard to read, really quickly.

  4. #3
    Sencha Premium Member skirtle's Avatar
    Join Date
    Oct 2010
    Location
    UK
    Posts
    3,474
    Answers
    523
    Vote Rating
    280
    skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future

      0  

    Default


    Personally I wouldn't use an itemId without putting it in the context of an owner container. I also try to avoid control queries that don't include a custom xtype. So assuming the grid doesn't have its own alias the selector might be something like 'userlist #gridPanel'.

    A couple of other things I would change...

    You should avoid using static ids, e.g. id: 'userlist'.

    Though it's difficult to be sure, it looks like your code might be suffering from excessive panel nesting. For example, here:

    Code:
    items: [{
        title: 'User List',
        items: [{
            xtype:'userlist',
            id: 'userlist'
        }],
        closable: false
    }]
    Why not just this?

    Code:
    items: [{
        closable: false,
        title: 'User List',
        xtype: 'userlist'
    }]
    Implicit in the selector in your original question is that your grid is wrapped in a yet another panel with xtype userlist. From the screenshot it isn't clear why. Shouldn't userlist be the grid?

  5. #4
    Sencha User
    Join Date
    Jan 2012
    Posts
    17
    Answers
    1
    Vote Rating
    0
    mminnie is on a distinguished road

      0  

    Default


    Quote Originally Posted by skirtle View Post
    Personally I wouldn't use an itemId without putting it in the context of an owner container. I also try to avoid control queries that don't include a custom xtype. So assuming the grid doesn't have its own alias the selector might be something like 'userlist #gridPanel'.
    Being new to ExtJS, I didn't realize the power of the component query. I looked through the generated HTML to determine how I would pinpoint the grid. Now I realize the component query can do this through xtypes (how....it can only be magic!). So my selector simply can be 'userlist gridview'. This is different from 'userlist #gridview'. The query didn't work with the hash mark before gridview. Am I missing something or was this an oversight on your post?

    And yes, I had excessive panel nesting. One reason, being a newbie and just getting it working. The other reason, I hadn't yet refactored my code.

    As for the userlist, it is a grid panel. I forgot to include the code in the original post.

    Code:
    Ext.define('LB.view.user.List' ,{
        extend: 'Ext.grid.Panel',
        alias : 'widget.userlist',
        store : 'Users',
        initComponent: function() {
            this.columns = [
                {header: 'User ID',  dataIndex: 'id',  resizable: false, width:55},
                {header: 'User Name',  dataIndex: 'username',  flex: 4},
                {header: 'First Name', dataIndex: 'firstname', flex: 6},
                {header: 'Last Name', dataIndex: 'lastname', flex: 6}
            ];
    
            this.callParent(arguments);
        }
    });
    @skirtle: Thanks for the clarification on everything, and thanks for going the extra mile in helping by pointing out places to improve the code above and beyond the original question. When I get enough knowledge, I will return the favor to forum users. For now, I'm feverishly learning!

  6. #5
    Sencha Premium Member skirtle's Avatar
    Join Date
    Oct 2010
    Location
    UK
    Posts
    3,474
    Answers
    523
    Vote Rating
    280
    skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future

      0  

    Default


    I suggest having a read of this page in the docs, it doesn't cover everything but it may fill in some of the blanks:

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

    It includes an explanation of the # syntax.

    The itemdblclick for a gridview is relayed by the grid itself, so there's no need to target the view specifically. Just listen for this event on the grid instead. You should end up with a CQ selector of just userlist.

  7. #6
    Sencha User
    Join Date
    Jan 2012
    Posts
    17
    Answers
    1
    Vote Rating
    0
    mminnie is on a distinguished road

      0  

    Default


    The # makes sense. It is just like a CSS definition. Thanks for the link.

    Can I assume the component query userlist with the itemdblclick does NOT fire when the grid header, which is part of the userlist component extended from grid panel, is double clicked because the grid header catches the event and prevents the event from bubbling up to the userlist component?

    Thanks again for taking the time to explain. Little bits of help like this keeps us newbies going.

  8. #7
    Touch Premium Member
    Join Date
    Nov 2009
    Location
    London
    Posts
    49
    Vote Rating
    6
    mattgoldspink is on a distinguished road

      0  

    Default


    Maybe this is just my preference, but I wouldn't even use the itemdblclick event in the controller. The way I like to look at my views and controllers is a little more higher level. A view is a representation of a model (or set of models) being displayed and the a view can allow a user to interact and perform actions. These actions are normally more high level, for example a double click on user might mean 'Edit this user', in that case I would get my view to relay an 'editUser' event with all the relevant details the controller might need.

    By taking this approach you can set yourself up to changing the view more easily without having to touch the controllers. For example if you decide you need a mobile interface then itemdblclick doesn't make sense any more and you'd need to either rewrite a new set of controllers to handle this, or add more complexity to the controller to handle 'itemdbltap' for example. However if you get all views to relay the same editUser event then the controller need not be changed. Another good example is re-use across multiple views, if your component query matches multiple views then you can relay this same event from anywhere, similarly if the editUser event in one view needs to be in a grid and in another view it comes from a button (perhaps a detailed user view) then there's no need to touch the controller.

    This is at least how we have been working with MVC in Sencha Touch and it has helped us to produce a phone ui first and then on tablets load a different set of views but re-use exactly the same controllers. We've also started doing the same with Ext 4.x and again it's helped a huge amount of complexity

    HTH,
    Matt

  9. #8
    Sencha Premium Member skirtle's Avatar
    Join Date
    Oct 2010
    Location
    UK
    Posts
    3,474
    Answers
    523
    Vote Rating
    280
    skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future

      0  

    Default


    Events prefixed with item are events for the items in a view (that's an Ext.view.View, not a view in the MVC sense). For a grid view the items are the rows. So itemdblclick only applies to rows, not the header.

    Regarding mapping events to more meaningful names like editUser. I can see the benefit of that but I haven't tried it myself so I can't speak from personal experience. Approaching it from a purely theoretically perspective, it feels like you're moving controller logic into the view. A view should understand concepts like clicks or keypresses and no more. Mapping to events such as editUser or deleteProduct is giving those events extra meaning at the view level. I think there's a clue in the names. itemdblclick describes an event that has occurred to the grid. editUser however does not - it describes how you want that event to be handled. That feels like the observable prejudging the observer to me. The decision to treat a double-click as an edit should be in the controller.

    My instinct would be to keep the view events descriptive of the user interactions. It seems pretty trivial to wire up multiple events to the same handler at the controller level without building extra logic into the view to abstract it away.

    Of course in practice I may be totally wrong... what's convenient in practice doesn't always tie up with theoretical idealism.

  10. #9
    Sencha User
    Join Date
    Jan 2012
    Posts
    17
    Answers
    1
    Vote Rating
    0
    mminnie is on a distinguished road

      0  

    Default


    Quote Originally Posted by mattgoldspink View Post

    By taking this approach you can set yourself up to changing the view more easily without having to touch the controllers. For example if you decide you need a mobile interface then itemdblclick doesn't make sense any more and you'd need to either rewrite a new set of controllers to handle this, or add more complexity to the controller to handle 'itemdbltap' for example. However if you get all views to relay the same editUser event then the controller need not be changed. Another good example is re-use across multiple views, if your component query matches multiple views then you can relay this same event from anywhere, similarly if the editUser event in one view needs to be in a grid and in another view it comes from a button (perhaps a detailed user view) then there's no need to touch the controller.
    Interesting approach. I see how having the same controller would have it's advantages. If the controller does not change, and the logic is to call a view EditUser, do you name the phone UI view and the tablet UI view the same and just reference the correct view in the app...such as appPhone.js and appTablet.js?

  11. #10
    jay@moduscreate.com's Avatar
    Join Date
    Mar 2007
    Location
    Frederick MD, NYC, DC
    Posts
    16,353
    Answers
    102
    Vote Rating
    77
    jay@moduscreate.com is a name known to all jay@moduscreate.com is a name known to all jay@moduscreate.com is a name known to all jay@moduscreate.com is a name known to all jay@moduscreate.com is a name known to all jay@moduscreate.com is a name known to all

      0  

    Default


    At all cost, do not use static ids. You will end up with an app that is brittle. Trust me on this.