Friday, July 22, 2011

ExtJs MVC- Dynamically Load Views

Hello,

Recently I tried ExtJs 4.0.2a and MVC application architecture and I must say that's an awesome improvement. Using MVC you have so much of flexibility. Now you can organize your whole application in proper structure that can be easily maintained and updated. It's really powerful feature available in ExtJs 4.0. You can get more details about this from this link. The MVC Architecture

They have explained a straight forward application with a grid with CRUD operations. What I will explain is dynamically loading views. Please read above article before further reading this post.

I was having requirement to dynamically load different views on all the the use actions. For example I have following four views for my content panel.

app/view/content/UsersGrid.js
app/view/content/ProjectsGrid.js
app/view/content/PremimumUsersGrid.js
app/view/content/PortfolioGrid.js

and let's say I have assigned following aliases to all of the above views.

UsersGrid => 'UsersGrid'
ProjectsGrid => 'ProjectsGrid'
PremimumUsersGrid => 'PremimumUsersGrid'
PortfolioGrid => 'PortfolioGrid'

I have a content panel in my view port and in which above views would be loaded dynamically. I can add reference of ContentPanel in my content controller to get the instance of it dynamically.


refs: [
        {
            ref :  'contentPanel',
            selector: 'ContentPanel'
        }
]

refs is the new way in MVC to get the reference of the the control. Above code will create a function getContentPanel() dynamically and I can use it to get reference of Content Panel. Here ref property specify name of function. Selector specify xtype of control. This xtype can be set using alias as follow.

alias : 'widget.ContentPanel'

Now consider I have a button. On click of button I want to load UsersGrid. Following will be code to load content panel and creating and adding view dynamically.

var contentPanel = this.getContentPanel();
contentPanel .removeAll(); //removing existing views.

var usersGrid = Ext.create('MyApp.view.Content.UsersGrid');

contentPanel.add(usersGrid);
contentPanel.doLayout();

Same way you can load other views as well.

13 comments:

  1. Thank you for this example. I have been trying to figure out how to do this...gracias!!!

    ReplyDelete
  2. Thanks for the example, but it's not enough for me. I want to dynamically load my views from a tree in the westpanel, but even from your example I cannot figure out where to put what. Don't yet understand your content controller either (and I think this is where it all happens).

    Could you explain this a little further?

    ReplyDelete
  3. Hi Marcel,

    In your case you must attach selection event of tree and dispatch an controller action and depending on tree node selection you can dynamically create view and render it to container.

    ReplyDelete
  4. Hi Hiren,

    got it. Thanks for your post and reply.

    ReplyDelete
  5. Hi Hiren,

    ran into another problem now. I have a border layout on one of the panels and I can't seem to reference the toolbar buttons anymore from the controller. Before I used

    'memberList button[action=addMember]': { click: addMember }

    in my controller to call a function on mouseclick. This is now not working anymore.

    Did you see this behaviour as well?

    Thanks for any reply

    ReplyDelete
  6. Hi Marcel,

    You can use DOM query to get reference of toolbar buttons. Assign itemId to toolbar buttons and you will get it with DOM query.

    ReplyDelete
  7. Yeah, I just found out I had some wrong code still in the controller that I used for debugging something else. It's working now. I was using Ext.DocumentQuery.query and that gave me the right reference, so I couldn't see what I was doing wrong. Simplified the code somewhat and found the old code. ;-)

    Thanks anyway!

    ReplyDelete
  8. Very interesting tutorial. It really helped me to understand better. I have a small question however. When you create a view with Ext.Create(....) will it every time load another new instance of the particular view?

    ReplyDelete
  9. This is wrong on oh so many ways! You should be using a parent panel with card layout to switch between your views, not removing everything and recreating it from scratch all the time.
    Which also answers the question of Dino Mifsud: yes, the method described in the article creates a new instance every time. Which is bad in so many aspects and definitely performance-wise.

    ReplyDelete
    Replies
    1. This tutorial just explains the dynamic load of views and just for example I wrote the code. This article was written when MVC was just introduced. I know after that it's improved a lot.

      Delete
  10. Can you share an example loading dynamically views?

    ReplyDelete
  11. Can you share an example loading dynamically views? pls

    ReplyDelete
  12. then how load views in container panel with card layout ? and if we are not removing any views after card change, is it going harm the performance ? I am using the same architecture in my application. I dont want to create views everytime on click of the menu. so I am going to do is load the view only once and use it there after. Is this the right way to go ?

    ReplyDelete