ExtJS4 - Store per panel instance? - extjs

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?

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:
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.
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.
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.
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).

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.

Related

AngularJS: create single controller but use it in different parts of the page with different data

I need to write piece of code with AngularJS which will build some table with logic. The information for the table should be obtained from the server. Under the table on the page there should be a button, which will create one more table, but (possibly) with different data from the server, and so on. So, I should use the same controller (because all logic remains the same in every next table), but data, some supporting variables and objects should be different for EVERY table. Previously loaded tables should also remain on the page and support all user functions binded to them. How I can do this? As far as I know, services are singleton objects, so this way is not acceptable.
This is actually what directives are for.
If that seems too complicated, ng-repeat will create a scope for each repeated item that you can then use in ng-controller.

Angular 2: Component input/output or updating a service property

Learning Angular 2 and trying to understand when I should use a component input/output and when I should better update a service property (possibly attached with an EventEmitter if updates are needed).
I have a list of, say, tasks, and each list items shows various info and options for this list item. This list works in the way that only one list item is active, and the active one is on the top of the list. One of those options for each list item is to activate it (if it is not already active), but other components could also possibly change which is the active item.
I have a parent task component, list component and a list-item component (and some other related components), and in addition I have a task-service.
The main taskcomponent could use listcomponent (and something-realted component, many of the components used needs to know and possibly change the activeItemId), like this:
<list [(active-item-id)]=“activeItemId”></list>
<something-related [(active-item-id)]=“activeItemId”></something-related>
The listcomponent could use list-item this way (active is a pipe and also a property on item):
<list-item *ngFor=“#item of items | active”
(item)=“item”
[(active-item-id)]=“activeItemId”>
</list-item>
But since I have a task-service that contains various task related, I could on the service use the already existing activeItemId-property (that has an eventemitter), and all the various task-components could just get info (and be updated) via this property, instead of “sending” the property back and forth via various components via inputs/outputs.
When would it be appropriate to just use a service for something like this and when would it be appropriate to use input/outputs for components instead?
Got a great answer via Angular Google Groups:
Without reading your full explanation, I'd say use binding if
possible, otherwise use a shared service.
Binding is not possible when
- the two components aren't direct parent/children
- the component is added by the router
- the component is added by DynamicComponentLoader
If you share the data between several components at once it might be
easier to not use binding even when one or some of them are direct
children.
Thank you, Günter!

backbone can a collection contain model objects of different classes?

I am just beginning to use backbone.js for a new crash project. My app has a dynamic (data-driven) user menu. Each menu option is a set of graphs/small tables, of mixed types. For example, a Sales Overview menu option can have a page with 2 pie chart objects, 2 line charts, a bar chart, and so on. I don't know up front what the menu options are going to be, nor what each menu option will entail.
I am considering defining a bunch of generic model "classes" by extending Backbone.Model - PieModel, BarModel, DispersionModel, etc. And corresponding View classes that can render an object of a type - PieView, LineView, and so on. Then I can assemble a page by putting these together as defined by the dynamic configuration. Each model instance's data url can be easily generated on the fly, via the dynamic configuration..
My first concern was if Backbone supports a Collection of mixed Model types. This is instigated by presence of a "model" property for a Collection - does it assume homogeneity? But it also says a collection can hold an ordered set of models.... model attribute can be polymorphic... a method to get "models" held in the collection. Should I be reading this as "model objects"?
A "page" to me really is a collection of such objects. I would like to create a Collection on the fly and populate it with instances of different model types. And then render this through a View. Or, create a View with an array of various model objects and render the View, bypassing the Collection all together.
I will appreciate your inputs on the design I have outlined, and good reference on backbone, and clarity on how to deploy a Collection in mixed model cases? Perhaps there is a different, smarter way to handle such scenarios...
Thanks.
Collections only really use their model attribute when passing plain objects into its adder functions (e.g. add, push). If you take a look at the source, each adder function passes the input through _prepareModel, which checks if the input is an instance of a Backbone.Model. If it's not, it tries to instantiate a new model using the collection's model, otherwise it just returns the input untouched.
So as long as you're always adding real Model objects to your collections you should be fine using different types.
However, if you're planning to use aggregate functions that act on model attributes (e.g. pluck) you may run into errors when the function tries to get at an attribute that doesn't exist in one type of model (though most of the time I think it would just silently fail, which might be what you want).
I am not sure if I have 100% properly understood your scenario, however, I am not convinced you are thinking about this in the right way...
In my opinion, your models should contain the data, and views should represent them. As such, in a sales context you might have a SalesData model which could be displayed in PieView, BarView or TableView. Try to completely separate display logic from data - the type of chart falls under display logic in my opinion.
With the above approach, each page would then contain a set of different views, which you could potentially contain in a master view if you felt the need. Each view would have its own model (or collection depending on how you structure the data), which you can then update/manipulate using the normal Backbone methods.
As far as I know it is not possible for a collection to have different types of models contained within it, but even if it was, I would probably not recommend it as it would complicate the code a lot.
In terms of learning resources, here are a couple:
Learn Backbone JS compeltely -- javascriptissexy.com - this one is very thorough but will take some time to get through.
Backbone patterns - much quicker to get you in the right frame of mind.

AngularJS Getting Setting more than one controller

I am new to AngularJS with FireBase as my data store. I have gone through the examples on their website. Now, I would like to expand on the simple concepts and create a more detailed application.
Let's say, for example, I have a recipe controller. This would contain the recipe name and a short description. But, I also want to have a list of ingredients along with their quantities.
The ingredients would be a select element with a list of available ingredients to choose from.
My question is, how do I utilize multiple controllers on a CRUD site? Or should I not use multiple controllers and somehow use the recipe controller to handle everything?
If I were doing this by creating the database schema in, say, MSSQL I would have no problem and would know exactly what to do. I think it's the fact that everything is client-side that is throwing me off.
Thanks in advance for any assistance provided.
You probably won't want to have a controller per entity. You're controller here maps to a scope object. The scope is then bound to a view - keeping them in sync.
So if your view displays a recipe (i.e name/description), it might also have a child property ingredients ($scope.recipe.ingredients).
You're controller will manage this 'recipe' object, and also provide methods to modify/retrieve/manage it. Say for example you want to save the $scope.reciepe object to your FireBase store - you can inject a service into your controller, and then make a $http call to 'put' that object into your db.
A brief conceptual overview of control
See more at https://docs.angularjs.org/guide/controller

Passing data from main application view to some subviews

Please consider following Backbone application structure:
AppView
Subview
FirstSubviewInQuestion
Subview
Subview
SecondSubviewInQuestion
Application view creates and stores a collection of special items. At a certain time the first and the second subview needs to get access to that collection. Now what is the best way to pass the collection it to them?
I myself see some ways, yet each has a downside:
1) Create instance of that collection not inside the App View but even more globally and then pass it around as dependency (project uses RequireJS; so it would be passed to AppView and both Subviews).
Downsides: app view is supposed to be the top most element in application. Yet suddenly we have some instances of collections floating above.
2) Or I can do following:
// some subview
var collection = {};
Backbone.trigger( "item:getSpecialItems", collection);
// now the collection has data
// app view
this.listenTo( "item:getSpecialItems", function(obj) {
// copy collection to passed object
_.extend(obj, this.specialCollection);
});
Downsides: we are triggering a global event. We know that only the app view would respond, but it feels like a bad design. Plus, this way to pass the collection seems like a hack.
Maybe there are some other clever ways to do it?
I would say #1.
app view is supposed to be the top most element in application
Right, but you're talking about (I think) a Collection, not a View; the two are totally separate parts of your application (in MVC the first is the "M" and the second is the "V"). By definition, if your views are driven by your data, the data must be "higher" (in the dependency tree) than any view, so I don't see anything wrong with that approach.
If your goal is to get a shared instance of the collection, my approach would be to pass that down from the parent to "subview" and from subview into its children. However, I wouldn't necessarily use require to pass around a singleton of this collection.
You could also pull out all of the logic from the view regarding the special methods for "creation and storage of special objects" into a helper class whose sole domain is just this. That helper then becomes a utility available from outside the view hierarchy, perhaps even globally or via require.

Resources