View Full Version : Dataviews and component communication

18 Apr 2012, 3:53 AM
I am very new in ExtJs4. I have a difficulty in understanding “XTemplate”, “dataview” and component communication in general. My project is builded respecting the “MVC” architecture.
The sort description of the app: I have a viewport that it is a border layout. It is separated in west and center regions. The west region is holding a tree panel (each node representing a member). When the user click a node, in the center region a tabpanel is created (each member has its own tabpanel). Inside the panel there is a border layout. The center region (this panel holds member’s biography), the east region (it is holding a list of the related to a member items: books, journals, cds), and the south region (when the user click on an item in the east region a preview of the item will be populated in this panel). It is looks like of Sencha’s “feedviewer” example.
When I click on a node the tab is builded successfully in the center region (the tabpanel’s title takes node’s title and the related views [border layout] are rendered inside the tabpanel). Also by clicking a node I am trying to load the related to views stores. Here is the problem. Clicking a node I am passing node’s id in the related store proxy url in order to retrieve data from server (memStore.proxy.url = 'http://localhost:8500/MVC/Book_Ledger/app/cf_scripts/Members.cfc?method=getAllMembers&id='+selectedMemberId). In firebug I can see the data returned from the server but it is not populated in the related panel (inside the tabpanel’s center region). In the tabpanel’s center region I have attached a “dataview” in order to format the received data. A weird thing is: in the “dataview” attributes I have set an empty text (emptyText: 'There is nothing here to see') and when the tab panel is rendered I can see the empty text but not the data that is served by the server!
What I am doing wrong here?
I have an attachment with the code (the code is just for reference). Unfortunately I haven’t tried it with static data because I am working with dynamic.
Any help is appreciated

18 Apr 2012, 6:43 AM
Hey again,

I looked at the code.

First, you should use the Rest proxy instead of the Ajax proxy in your model. The rest proxy will generate the correct urls for getting, creating, updating and deleting instead of you messing around with the url like you're doing in the nodeselection handler.

if(tabTitle != "Members" && tabTitle != "New Members"){
memStore.filter('id', selectedMemberId);*/
memStore.proxy.url = 'http://localhost:8500/MVC/Book_Ledger/app/cf_scripts/Members.cfc?method=getAllMembers&id='+selectedMemberId


This stuff is kind of weird because what you want is to load a single Member, not an index right? so why are you reloading the store, which gets many Members? Also, the store is not connected to anything, which is why no data is showing up. Really you just want to load a single Member model like this:

var memberModel = Ext.ModelManager.getModel('Ledger.model.Membersmodel');
memberModel.load(selectedMemberId, {
success: function(record, operation) {
//create the tab, and load it with the record
failure: function() {
Ext.MessageBox.alert('Request Failed', 'Failed to load Member');
scope: me

Your Memberview should have a load function that takes a Member record and puts its data in the right places.

Also, try to use the naming conventions in the examples. Don't call it Ledger.model.Membermodel. Call it Ledger.model.Member etc.

Hope that's enough to start.

18 Apr 2012, 10:49 AM
Thank you dogomatic for your response,
I really want to use rest proxy but I don’t know how. I suspect that I have to build an api in the server side (I am using ColdFusion) in order to process the “GET”, “POST”, “PUT” and “DELETE” requests. This is not an option if it is true because I don’t know how to build it. So, I have to use the url.
Passing the url in the proxy like ( memStore.proxy.url = 'http://localhost:8500/MVC/Book_Ledger/app/cf_scripts/Members.cfc?method=getAllMembers&id='+selectedMemberId) I having a return of a single member info. This store is responsible to store a single member and it is bind to a “dataview” (I will talk for this “dataview” later). When I am reloading the store what I am seeing in firebug is the info for the specific member. I don’t want to load an index because members’ info may be from 500kb to 4MB!
The “Memberview” is a tab that holds tree panels as border layout (center, east and south). What I want is to load member’s info in the center panel (related items as a list in the east panel). In the center section I had attached a “dataview” and its store is the “memStore” (the store that I am passing the “selectedMemberId” see above). When I click on a node memStore is loaded with a single’s member data. But the “dataview” shows nothing (exept the epty text!). The center region of the tab is in the Biog.js .
I am struggling to find a solution.
Thank you again,

18 Apr 2012, 10:45 PM
If you can't make your server side handle restful urls like /members/1 you can make a custom proxy to create whatever kinds of urls you want, although this might be a bit advanced for you... You can copy src/data/proxy/Rest.js and make the changes you need to buildUrl and actionMethods.

Of course if you load all your data into the store it will be too big. Usually for an index query you don't return all the data for each Member - maybe just the name to show in the Tree. This is why with a rest interface the query for the index (members/) is different from the query for a single instance (members/123). Only return what you need in the index query. You handle them differently on the server.

Really, I'd start from the nested-loading MVC example. From there you need to make these changes:
1) put the proxy on the Model instead of the Store
2) in Books.controller.Books:onSideBarSelectionChange, change it to load a single instance like I showed in my last post above.

Sounds like you have a long way to go. MVC is hard, and the examples are incomplete. Keep trying different approaches and see what works for you.

19 Apr 2012, 12:47 AM
Hello dogomatic,

I am very obligated for the reason that you answering me promptly. I have few questions:

> You are telling to put the proxy on the Model instead of the Store. Isn’t it the same?

> You are telling me to change the “onSideBarSelectionChange”. By changing this am I going to load single’s member data? I think it is not possible because the data is already nested.

> Finally I have solved my loading problem. I didn’t write correctly the template (“dataview”) that is formatting the retuned by the server data. But a new problem raised: when I click a node a new tab opens and the “memStore” store loads the data. All the tabs are refreshed with the data of the last store request. I think this is happening because I am using the same store for all the newly created tabs. The solution is on each tab creation to make a new instance of the “memStore”. I don’t know how to do this. Can you help me?

> In the Book_Ledger app there is a controller (Ctrltree.js). In the line 18 (refs), I tried to make a reference for the dynamically created tabs. In line 67 I tried to reference to the newly created tab and I got an error: “getBiog is not defined”. How do I reference to a component that it is not yet rendered? (If possible)

> One last thing: my major problem is that my database will return more than one datatypes (txt and pdf). Practically in a member’s tab the data will be txt and or pdf (converting pdfs is not an option). How a component can display more than one datatypes? Is there any idea in how to address this problem?

I will try to find resources on RestFul architecture. It seems to be very fascinating way to build an app.

Sorry for asking so many questions.

Thank you again,

19 Apr 2012, 9:05 PM
Hey Tom, I think we're misunderstanding each other because of the language barrier. I have some free time right now though, so I updated the nested-loading example to do what I've been saying.


Open it in chrome using the --allow-file-access-from-files command line argument to allow local Ajax.

20 Apr 2012, 1:10 AM
Thank you for the example, but it doesn’t work. It seems that something is missing. I received two errors: “404 Not Found- ../data/association/BelongsTo.js” and “404 Not Found- ../data/association/HasMany.js”. Anyway, as for the “misunderstanding issue”, I understand you 100%. Maybe my rush to ask you as many questions as I can, affect my writing style. Notice also, that I am a “rookie” in programming. I don’t want to be a burden to you. So, I will try to rephrase two questions from my last post.
> Is it possible to make a reference (refs) to a component that will be created dynamically? (not yet created)
> How can I display in a specific “view” pdf, txt or any file type?
Thank you again my friend,

20 Apr 2012, 2:31 AM
Try messing around with the directories. It works for me in Chrome and firefox.

> Is it possible to make a reference (refs) to a component that will be created dynamically? (not yet created)

I don't think so. Usually in that situation, I'll save a reference or use Ext.ComponentQuery.query().

> How can I display in a specific “view” pdf, txt or any file type?

haven't tried this. For txt it might be better to query it and dump it a view. For a pdf, I don't know sorry.

20 Apr 2012, 2:44 AM
Thank you