dynamically load tree's child nodes on folder open - extjs

I'm new to extjs and I'm trying to work on a Tree view.
I am building an "API Explorer" and there are simply too many nodes to send as a single json object (a few million nodes). What I wanted to do instead was send the first layer of categories as json initially, then on expand do an ajax request to get all of that category's children.
I'm not sure how to do this or if it's possible. Can anyone lead me in the right direction?

Actually that is the "normal" way as suggested by the documentation. Have a look at any of the Tree examples.
You basically set up an Ext.data.TreeStore with a Proxy, e.g. an Ext.data.proxy.Ajax:
xtype: 'treepanel',
loadMask: {msg: 'Loading...'},
store: Ext.create('Ext.data.TreeStore', {
proxy: {
type: 'ajax',
url: 'get-nodes.php'
}
})
Each time the user expands one of the nodes, the URL will be hit with the parameter node set to the id of the expanded node and should return an array of the children of this node. These children must not have a children property theirselves, otherwise they would be considered already loaded and would not be loaded on expansion.

Related

Unable to show data in ExtJS Tree Grid

I just copied the example of ExtJS tree grid from Sencha's site. I created a fiddle with only difference being, I am using local data instead of using proxy & I have removed some columns.
Please check this fiddle and tell me why I am not able to see data in the grid?
Thank you!!!
Tree stores don't have a data option (search for it in the docs). Memory proxies, on the other hand, do. So you can put your data in it to solve your problem:
var store = Ext.create('Ext.data.TreeStore', {
model: 'Task',
proxy: {
data: JData,
type: 'memory'
},
folderSort: true
});

ExtJS 4. Hidden treepanel with autoload false

I have a treepanel inside my form. The code is
{
xtype:'treepanel',
rootVisible:false,
hidden:true,
autoload:false,
store:{autoload:false,proxy:{type:'ajax',url:'../json/objectList.php?id='+id},root:{text:'Objects',id:'src',expanded:true}},
listeners:{
show:function(){
this.store.load();
}
}
}
The problem is, I want to prevent loading before the tree is shown. But setting autoload to false does not have any effect. I still see a server request, even if the tree is hidden.
The autoLoad property does not work for tree stores as the load is based on the expansion of the node as you are doing for root. This is what I do to overcome it.
In your store confing
root:{
text:'Objects',
id:'src',
expanded:true,
children:[]
}
Setting an empty children object will prevent the store load. Then all you need to do is set up a listener on the tree view to load the store as you have done. You will need to modify the server code to return the data without the children property...so just the array.

How can I handle several store instance in the same action using Sencha Touch 2?

I coded a simple application which displays a dataview.List articles in the home page.
Here's a view of my home page :
I can also open a specific article by clicking on it and have its complete description in an other view.
Here's my article view page for a specific article :
To do this I apply a filter in my ArticleController class (here I get the matched record).
onViewArticle: function(record) {
var articleStore = Ext.getStore("ArticleStore");
var selectedArticle = record;
articleStore.filterBy(function(record, id) {
if (selectedArticle.data.id == id)
return (true);
return (false);
});
Ext.Viewport.animateActiveItem(this.getArticleViewConnexContainer(), {
type: "slide", direction: "left"
});
},
And here's my store class :
Ext.define("MyApp.store.ArticleStore", {
extend: "Ext.data.Store",
requires: ["MyApp.model.ArticleModel"],
config: {
model: "MyApp.model.ArticleModel",
proxy: {
type: "ajax",
api: {
create: "http://localhost/MobileApplication/MyApp/services/ArticleService.php?action=create",
read: "http://localhost/MobileApplication/MyApp/services/ArticleService.php?action=read",
update: "http://localhost/MobileApplication/MyApp/services/ArticleService.php?action=update",
destroy: "http://localhost/MobileApplication/MyApp/services/ArticleService.php?action=destroy"
},
extraParams: {
keyword: ""
},
reader: {
type: "json",
rootProperty: "articles",
totalProperty: "total"
}
},
autoLoad: true
}
});
But now, I want to apply another filter in the same action to list others articles (with another specific filter) just below the article description. This involve to use two differents filters I think (one to get back the specific article (already done here) and an other one for the article list I want just below the article description). But how can I do this ? If I apply two filters in the same controller function, the second one will destroy the prevent one because all store data are in the cache. Is there a possible way (like in php MVC frameworks for instance) to send a variable from the controller to the view and display its content (By this way I will have two differents variables and I will can display the content of my two requests on my view)? Or maybe a possible way to handle several stores in the same time ? I'm really lost. Does anyone can help me, please ? Thanks in advance for your help.
There are actually couple questions inside.
Sencha Framework is built with "one store - one view" concept in mind. So if you have two different view presenting information from really one data store, you still would need to have two copies of this store. You can clear/apply back filters if you don't need to show these two views at the same time (it's mostly true in case of phone applications), but I would recommend to have two separate copies.
As far as your scenario - I don't think you need that. When you're displaying particular book you don't need to filter store. You need to just load one record (store.getAt()) and then use this record in your child form.

ExtJS 4 URL is undefined when I try store.load()

I have a Panel with multiple grids. I'm trying to make some kind of global refresh button by which I mean, a button that will refresh all the grids and open tabs, without losing data like when F5 is pressed.
With two of the grids it was easy just get the store and load it but the third one makes a problem. When I try the same as with the previous two which works OK I get URL is undefined.
Here is my code:
reloadInstructionsStore: function() {
var reloadInstructionSt = this.getStore('Instructions');
var activeCat = this.getActiveCategory();
reloadInstructionSt.clearFilter(true);
reloadInstructionSt.filter({
filterFn: function(item) {
return item.get('category_id') == activeCat;
}
}),
reloadInstructionSt.load();
},
The only reason I can think of is that the store that I use here is defined different from the other 2. It's not with PROXY and CRUD, but looks like this:
Ext.define('MY.store.Instructions', {
extend: 'Ext.data.Store',
model: 'MY.model.InstructionRecord',
autoLoad: true,
data: g_settings.instructionsApi.initialData
});
Is the problem here and is there a way to make things work even like this?
Thanks
Leron
You do not need to reload this store, the data is provided on initial page load. The variable g_settings.instructionsApi.initialData tells me that the data is available as static on the page. All you need to do in this case is reset the filter, and just remove the reloadInstructionSt.load(); call.
If you actually do want the data to reload from the server, you will need to give your store a url that it can get the data from and the server will have to be able to serve this data up.

Updating EXTJS 4 Treepanel periodic

I would like to create a Treepanel, which is updated once a second.
So I took a store with a proxy for data acquistion:
store = new Ext.data.TreeStore({
model: 'TaskState',
proxy: {
type: 'ajax',
url : '/getTaskList'
},
root: {
expanded: true
}});
The store seems to work, the data is displayed in my TreePanel.
I tried to update the Treepanel with this function:
function refresh(){
store.load();
window.setTimeout("refresh()", 1000);
}
The update seems to work as well. Unfortunately the update causes some kind of "blinking" effekt on every update, because the whole tree is reloaded. I'm searching for a way to only refresh the nodes, which have changed.
Is there some way to do this?
greetings
There is one way:
You can load your nodes to some temp store and change your main tree's store node by node
If you want to add any new node and do not want to reload the whole store then you can add like this
//overModel is Ext.data.Model
overModel.appendChild({
id: responseJson.data['id'],
text:responseJson.data['text'],
children:responseJson.data['children'],//array of childern
parent_id:responseJson.data['parent_id']
});
overModel.expand();
and if you want to load the whole store the you can do something like this
Ext.data.StoreManager.lookup('StoreName').load({ params: {"p1": p1}});
to load the store.
To update the store periodically you can use DelatedTask Class.
check out the Documentation API of EXTJS will give you more details.
Store is bind Treepanel like grid and store ,so you can get Store from tree panel with
var store=treepanel.getStore()
and you can reload the store with branch that you need update with
store.load({node:selectedNode})
You could use TaskManager for that:
Ext.TaskManager.start({
run: reloadStoreFunction,
interval: 1000
});
This would execute reloadStoreFunction every second.

Resources