ExtJS 4 MVC multiple instances of views and sub/child controller difficulties

蹲街弑〆低调 提交于 2019-12-03 05:33:46

I was faced with a similar problem:

Consider a tabpanel for a CRM type application which opens new instances of a view for each client. And say that tab view contains 3 or 4 row-editing gridpanels for interacting with different collections of data relating to that client.

The solution I came up with was based on this from the Sencha forums. In a nut shell, almost all events that are dispatched from a view contain a reference to the view itself. The handlers in my controller's control function all use these to get a reference to the correct view instance.

For dealing with the multiple instances of the same store needed for this, I took this to heart from that post:

For the Store instance on the view or a global one... depends on the needs. If you are going to use globally then make it global. If you only are going to need it on the view then put it on the view. MVC is not a law, you can change it to fit your needs. Technically the Controller part of MVC is suppose to be the middle man between the View and Model parts but sometimes that's just not needed. I create the Store in the view 95% of the time. I'll give you an example...

If you have a Store for products, you probably only need to reference that Store in your Grid. That usually isn't needed for other parts of the application. However, if you have a Store to load countries, I often need it globally so I only have to load it once and can then set/use that Store in several views.

So I just created the needed store's that relate to a view instance specifically, inside the view's initComponent method. The application did have a few global stores that I created as store classes following the MVC recommendations. It worked out nicely to encapsulate the view instance stores inside the view. Then I only needed one instance of the controller.

To answer your question specifically, currently, there is no ExtJS official recommendation or config for dealing with multiple instances of the same view that use the same store constructor. I have spent some time looking for something like that and the best I have found was this recommendation from one of their forum moderators.

I don't think you ever need more than 1 instance of a controller, regardless of how many views/models you have. See functional example here:

http://whatisextjs.com/extjs-4-extension/fieldset-w-dynamic-controls-7

This can be done, reasonably easily. You need to follow a few rules:

  1. load your controllers at app startup. Don't unload them. Don't worry about the memory or time, it's pretty small even for hundreds of controllers, as long as you minimize and concatenate your js.

  2. Never use the refs or views properties of a controller. You are going to use one instance of a controller, but multiple instances of views, so you never want a reference to a view.

  3. only use event listeners in controllers. You are only going to listen to events on your views. You can always get a (temporary) reference to a view in the event handler via the "cmp" parameter in the handler.

  4. To "launch" a view, create it and add it to another view. To destroy it, destroy it. You don't use a controller to launch a view. You can use the afterrender and beforedestroy events in the controller to add logic.

In ExtJS' MVC the controller is a Singleton for you view. I like how DeftJS thinks about MVC. Each instance of a view has an own instance of a controller. In this way you can put all "controlling rules" in a controller for a particular part of your view, and this will be instantiated only when the view opens.

I did not have any experience how I could use multiple Defts JS apps in the same project.

Of course. What led you to believe otherwise? Here is an example of creating a custom View which extends from a Window component. You can run this method many times from the same controller and each time you will get a new instance of a View.

"this" refers to a controller that code runs in:

       this.getRequestModel().load(requestID,{       //load from server (async)
                 success: function(record, operation) {
                        var view = Ext.widget('requestEdit',{
                            title: 'MyRequest '+requestID
                        });
                        var form = view.down('form');
                        form.loadRecord(record);
                 }
         });

How do you create your views? I see no reason why you cannot pass a different store or config data to every object. Some code samples would help for what exactly you are doing. For example, we have a similar sounding application, and everything is done with extensions. So, if we need a grid, we run

Ext.define('MyApp.grids.something',{
extends:'Ext.grid.panel' 
//...

These classes are predefined. Then, when a controller or view is loading this grid, they are using

var grid=Ext.create('MyApp.grids.something',{id:'unique',store:mystore});

As you can see, we can pass in different config options to the same grid each time it is created. We can treat this exactly as you would treat

Ext.create('Ext.grid.Panel');

Except of course that we make some options predefined, and some non-override-able, and so on.

Hope this helped.

Check out this post. The idea there is to take some configuration (like store and itemId) from view config and put it into the viewport config:

// .../app/view/Viewport.js
Ext.define('MyApp.view.Viewport', {
    // ...
    items: [
        // ...
        { xtype: 'testview', store: 'Store1', itemId: 'instance1' },
        { xtype: 'testview', store: 'Store2', itemId: 'instance2' }
    ]
});

The problem with store will be solved, obviously. Different itemIds will enable you to handle events properly.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!