6

I'm really new to the MVC pattern in Ext. I have a tabpanel with multiple instances of the same component (let's call it product), each should call the server when it's opened, with an id parameter.

Right now, in order to create these tabs - I use this in the Product controller Which creates a new instance of a view, but I feel like it's really incorrect.

createMainView: function (opts) {
    return Ext.widget("productDisplay", opts);
}

I call it from my "main" controller, like this:

var tab = this.application.getController("Products")
    .createMainView({ productId : id, closable: true })

tabs.add(tab);
tabs.setActiveTab(tab);

What's the correct way to properly use multiple instances of a view, each having an instance of one store and behavior (via the controller).

Can I use one named store for them (with a js file under app/store/product.js)?

Should I manually call load on the store from the controller (to pass the productId), or is there a nicer way?

Madd0g
  • 3,841
  • 5
  • 37
  • 59

2 Answers2

6

It's kind of very broad and interesting question which require big and thorough explanation (which you can find btw on the Sencha.com in their guides and manuals). I would like highlight couple points so you have something to start with:

  1. Stores are usually global objects. You don't keep two instances of one store in general. You can use filtering (local or remote) if you need to present information from the that store in several different views. The only time you would need to clone store is if you want to present different information from that store in 2+ different views at the same time.

  2. Controllers are usually spawned by main application object. You don't have to do anything special - just list them in the controllers: [] property. And then spawed when application is launched (before their views are created and rendered). Keep that in mind.

  3. If you have modal view - it's ok to create it manually and either re-use it or destroy and re-create later. You can add filtering and loading to controller which creates these views. And you can re-use same view/controller objects for different tabs if you want.

  4. If your views are presenting one instance of an object (like one product is displayed on each tab) - don't attach stores to those views. Just pass them individual model (record).

sha
  • 17,824
  • 5
  • 63
  • 98
  • thank you for your answers. I've seen examples of store filtering before, but that was when there's one view that is fed the filtered data, in my case there are multiple tabs that exist at the same time, each displaying different data (of the same type, that's why I asked about duplicating the store), they are not modal (if you mean modal like prompt), they exist at the same time. – Madd0g Apr 16 '12 at 15:36
  • So do you need a store (array basically) in each view or just model (record)? – sha Apr 16 '12 at 15:47
  • I didn't know that record can be used outside of a store - I guess that's why a model can have a proxy. Can a single record have load/save/bind functionality? – Madd0g Apr 16 '12 at 15:52
  • If you just pass a reference on your record to the view/controller and your store has autoSync: true everything should work transparently. Also if you need to call store methods from such view/controller - record does have reference to its store - you can call it. – sha Apr 16 '12 at 15:56
  • So it does have to be in a store beforehand? What if it's a paging store and the record is no longer in the store? Will it still be able to `autoSync` normally? – Madd0g Apr 16 '12 at 16:02
  • I'm not sure about that. You will have to test it out :) – sha Apr 16 '12 at 16:03
  • Well, I've read a lot about this today, [here](http://www.sencha.com/forum/showthread.php?131671-Advanced-MVC-Best-Practices/) and [databinding](http://www.sencha.com/forum/showthread.php?139149-DataBinding-in-ExtJs-4), and other threads. It looks like there aren't built-in (or nice for that matter) solutions for this problem. Now I have to decide whether to do some hacking and manual databinding or looking for a different MVC library. Thanks a lot @sha. – Madd0g Apr 19 '12 at 14:35
0

I would recommend creating the stores that relate only to that view instance inside of the view's initComponent method.

Your controller's control handlers should be coded in a way that they can differentiate which view dispatched the event. This should not be too difficult because almost all view events contain a reference to the component which fired the event. You could then use the relative query selectors, e.g.: myEventFiringComponent.up('anotherComponent') or myEventFiringComponent.down('anotherComponent') to get a handle on a different component in the same view if you need to.

Please see this post for a full explanation.

Community
  • 1
  • 1
egerardus
  • 11,316
  • 12
  • 80
  • 123
  • Thanks Geronimo, that's exactly what I ended up doing. I'm creating the store under `initComponent` and making sure that everything under `this.control` can reference the specific view (and what doesn't - I try to wrap in my own `fireEvent`). – Madd0g May 02 '12 at 19:55