TreePanel in ExtJs with direct proxy behaves weird - extjs

I'm using Sencha Architect 3.0.1.
I'm trying to use a Model, a TreeStore, and a TreePanel.
The Model:
Ext.define('User.model.ModelClientList', {
extend: 'Ext.data.Model',
fields: [{ name: 'id' }, { name: 'name' }, { name: 'status' } ],
proxy: {
type: 'direct',
directFn: 'UserClient.listClient',
reader: { type: 'json',root: 'data'}
}
});
The TreeStore:
Ext.define('User.store.StoreClientList', {
extend: 'Ext.data.TreeStore',
constructor: function(cfg) {
var me = this;
cfg = cfg || {};
me.callParent([Ext.apply({
model: 'User.model.ModelClientList',
storeId: 'StoreClientList'
}, cfg)]);
}
});
And the TreePanel:
{
xtype: 'treepanel',
height: 250,
itemId: 'MainClient',
width: 400,
title: 'Clients',
hideHeaders: false,
store: 'StoreClientList',
rootVisible: false,
viewConfig: {loadMask: true},
columns: [
{xtype: 'treecolumn',dataIndex: 'name',text: '..'},
{xtype: 'gridcolumn', dataIndex: 'status', text: '..'}
]
}
The json request to UserClient.listClient returns this:
{
"data":[
{"id":1,"name":"Pluto","status":3,"children":[
{"id":35,"name":"Mela","status":2,"leaf":true},
{"id":36,"name":"Pera","status":1,"leaf":true},
{"id":37,"name":"Arancia","status":1,"leaf":true}]},
{"id":2,"name":"Pippo","status":1,"leaf":true},
{"id":3,"name":"Paperino","status":2,"leaf":true}],
"success":true
}
Now, can someone explain me:
(1) Why, when I click on [+] icon of the first node the application does another ajax request instead of expanding what already got from the previous request
(2) Given this initial view:
Why when I click on the [+] it starts going crazy like this:

It was clearly a problem of Sencha Architect.
I rewrote from scratch in a new project the same architecture and now it works as expected.
Also, I noticed that something was going wrong with Architect becouse of simple operation made it show incomprehensible and undebuggable errors (like "Cannot set property 'DirectCfg' of null").
Unfortunately I cannot state that Sencha Architect is mature for large and complex project.. probably not even for small project. what a pity

Related

ExtJS 6 store.remove(records) -> store.sync() don't trigger the server

I use ExtJS 6.0.0, REST proxy with TreeStore. So when i remove some records from the store store.remove(records), then try to sync changes with server and call store.sync() and nothing happend! A callback function of sync not called.
url: '/admin/pages', return simple nested data in proper format.
View and update operations work well.
I made a simple code fragment just to illustrate the issue:
Ext.define('Pages', {
extend: 'Ext.data.TreeModel',
fields: [
{name: 'id', type: 'int'},
{name: 'parent_id', type: 'int'},
{name: 'title', type: 'string'}
]
});
Ext.onReady(function() {
var store = Ext.create('Ext.data.TreeStore', {
model: 'Pages',
proxy: {
type: 'rest',
url: '/admin/pages',
}
});
var tree = Ext.create('Ext.tree.Panel', {
width: 500,
height: 300,
renderTo: Ext.getBody(),
rootVisible: false,
store: store,
multiSelect: true,
columns: [{
xtype: 'treecolumn',
text: 'title',
sortable: true,
dataIndex: 'title'
}],
tbar: [
{
text: 'Delete',
handler: function () {
var records = tree.getSelection();
store.remove(records); // remove nodes from tree
store.sync(); // do nothing!! WHY?
},
}
]
});
If the store is configured as autoSync:true the record's endEdit method will have already internally caused a save to execute on the store. We only need to save manually when autoSync is false, otherwise, we'll create duplicate transactions.
You need to the call the store.load() after you do the syncing using store.sync()

Extjs5 store load is requesting a model file even when the model is defined in the same file

I don't know if this is a configuration issue in my app because I have done the same thing on one server which works perfectly. On a different web server I am trying to set up I am just trying to get an example working and I'm running into some extremely odd behavior. For some reason whenever the store loads it does a get request for a file that has the same name as the model name of the store. I don't understand why it's requesting a model file when the model is defined in the same file!? I didn't always have the model or store defined in the same file, they were in the proper directory structure but I moved them into one file to troubleshoot this issue and rule out possibilities but it's the same result, so for simplicity it's in the same file:
Ext.define('FPTModel', {
extend: 'Ext.data.Model',
fields: [
{name: 'f1', type: 'int'},
{name: 'f2', type: 'string'},
]
});
Ext.define('appName.view.main.Main', {
extend: 'Ext.container.Container',
requires: [...my controller and viewModel are here...],
xtype: 'app-main',
initComponent: function() {
var myStore = Ext.create('Ext.data.Store', {
model: 'FPTModel',
data: [
{f1: 1, f2: 'someData'},
{f1: 2, f2: 'some more data'},
],
autoLoad: true
});
this.testStore = myStore;
this.callParent();
},
controller: 'main',
viewModel: {
type: 'main'
},
layout: {
type: 'border'
},
items: [{
region: 'center',
xtype: 'tabpanel',
items: [{
title: 'tab 1',
xtype: 'container',
layout: 'vbox',
items: [{
xtype: 'grid',
height: 300,
width: '100%',
columns: [
{header: 'Field 1', dataIndex: 'f1' },
{header: 'Field 2',dataIndex: 'f2'},
],
store: this.testStore
}]
}]
}]
});
When the page loads everything is fine and there are no errors. Whenever the store loads I see a GET request go out for https://my.site/FPTModel?_dc=1432862899334&page=1&start=0&limit=25
I know this is happening when the store loads because when I remove the autoLoad it doesn't send the get request and if I call testStore.load anywhere it does the get request.
This get request returns 404 obviously because that file doesn't exist. I don't understand why it's trying to load the model file from the server's root directory, or at all, when it's already defined. When I had this defined in it's proper directory structure (appName.model.FPTModel) then the get request was for .../appName.model.FPTModel...
I have been using extjs for about 2 years now and I have never seen anything like this.... Hoping someone out there can shed some light on this as it's driving me crazy. I hope there is something simple that I am missing somewhere...
This is because you do an Ext.define on the model.
Then Extjs is going to look in namespace of your app and tries to find the model FPTModel as an FPTModel.js file, because you used just "FPTModel", in the root of your app.
You should use Ext.create to create the model as a variable result and use that variable (containing the model object) in in your store. Or you should create an additional file with the model description in folder: appName/model/ and refer to it in the store.
But then you have to add a require config setting in your store to the model. Something like
require: ['appName.model.FPTModel']
You don't have to do this if you have add the model and store to the requires of your application.js in your app.
If you have no further needs for the model I would include the fields in the store definition.
I have done some restructuring of your object (not complete). I have added some panels for clarity. Don't use a border layout if you don't need one and avoid overdoing layouts and unneccessary nesting of panels.
I have added the function getGridStore which you can call with this.getGridStore(), to avoid functions like this.teststore = myStore.
So if you have to reload the store you simply do: this.getGridStore().load(), or in the application or view controller something like: this.getMainPanel.getGridStore().load().
The autoLoad config is not required, because the store already holds the data. It is only required if you load the data from a proxy (server).
Ext.define('appName.view.main.Main', {
extend: 'Ext.panel.Panel',
layout: 'border',
requires: [],
xtype: 'app-main',
controller: 'main',
viewModel: {
type: 'main'
},
initComponent: function () {
var myModel = Ext.create('Ext.data.Model', {
fields: [
{name: 'f1', type: 'int'},
{name: 'f2', type: 'string'},
]
});
var myStore = Ext.create('Ext.data.Store', {
model: myModel,
data: [
{f1: 1, f2: 'someData'},
{f1: 2, f2: 'some more data'},
],
autoLoad: true
});
Ext.applyIf(this, {
items: [{
region: 'center',
title: 'Center Panel',
flex: 3,
xtype: 'tabpanel',
items: [{
title: 'tab 1',
xtype: 'gridpanel',
layout: 'fit', // maybe not even neccessary
columns: [
{header: 'Field 1', dataIndex: 'f1'},
{header: 'Field 2', dataIndex: 'f2'},
],
store: myStore
}, {
xtype: 'panel',
html: 'Some other tab',
layout: 'fit'
}]
}, {
xtype: 'panel',
region: 'east',
flex: 1,
html: 'East panel',
title: 'East Panel'
}]
});
this.callParent();
},
getGridStore: function() {
return this.down('gridpanel').getStore();
}
});
Because you're specifying autoLoad, which is triggering the store to send a load request. Since you've not provided a URL for the proxy, it defaults to the name of the model. Remove autoLoad, it's redundant.

Wrong ExtJS5 Grid render

Learning ExtJS5 I have a problem with grid. I have such panel description:
{
xtype: 'tabpanel',
items: [
{
title: 'Texts',
xtype: 'gridpanel',
reference: 'textGrid',
store: Ext.create('Ext.data.Store', {
fields: ['active', 'textValue'],
data: {
items: [
{active: true, textValue: 'test'},
{active: false, textValue: 'no test'}
]
},
proxy: {
type: 'memory',
reader: {
type: 'json',
rootProperty: 'items'
}
}
}),
columns: [
{ xtype: 'checkcolumn',
text: 'Enable', dataIndex: 'active', width: 100,
editor: {
xtype: 'checkbox',
cls: 'x-grid-checkheader-editor'
}
},
{ text: 'Value', dataIndex: 'textValue', flex: 1,
editor: {
xtype: 'textfield',
allowBlank: false
}
}
],
plugins: {
ptype: 'rowediting',
clicksToEdit: 1
}
},
{
title: 'Images',
xtype: 'gridpanel'
}
]
}
But it's rendered wrong. I don't see a checkbox and area for text column is too small. There're no any errors in firebug console.
What's wrong with code?
Thanks.
I had this problem too and it looks like this sometimes happens when there are requires missing in your classes.
Look into the console for warnings like these:
[Ext.Loader] Synchronously loading 'Ext.layout.container.Border'; consider adding Ext.require('Ext.layout.container.Border') above Ext.onReady
And add the missing classes to the requires array of the class that uses them like this:
Ext.define('Test.view.main.Main', {
extend: 'Ext.container.Container',
requires: [
'Ext.layout.container.Border',
'Ext.tab.Panel'
],
...
Styles are missing.
If you created the proyect with Sencha Command (you are loading proyect with microloader bootstrap, see your index.html), then you must be sure you have defined all requires of the components that you used on your app and launch this command from the root directory:
sencha app build
This command compile the css that will be use on your app (among other things). You can try too:
sencha app refresh
And a latest two command if the latest don't work (use both):
sencha app clean
sencha app build
Hope it work

Extjs grid cant get store buffered working

I have a large dataset (over 80k records). So I am trying to implement buffer but I couldn't get it work. If I include buffered configuration I am getting error object doesn't support this property. When I remove it, works ok but of course it takes forever to load the data.
Here is my code
Ext.Loader.setConfig({
enabled: true,
disableCaching: false
});
Ext.require(['Ext.data.*', 'Ext.grid.*',
'Ext.grid.plugin.BufferedRenderer', 'Ext.ux.grid.FiltersFeature']);
Ext.define('Borrower', {
extend: 'Ext.data.Model',
fields: [{
name: 'Name',
type: 'string'
}, {
name: 'Num',
type:
'string'
}]
});
Ext.onReady(function () {
var store = Ext.create('Ext.data.Store', {
autoLoad: false,
model: 'Borrower',
pageSize: 100,
buffered: true, // getting error object doestn support this property in extjs-all-debug.js
proxy: {
type: 'rest',
url: 'borrBuff.xsp/byName',
reader: {
type: 'json',
root: 'items'
}
}
});
var filters = {
ftype: 'filters',
encode: false,
local: true
};
var grid = Ext.create('Ext.grid.Panel', {
id: 'testgrid',
store: store,
features: [filters],
plugins: 'bufferedrenderer',
columns: [{
text: 'Borr Name',
dataIndex: 'Name',
filterable: true
}, {
text: 'Number',
dataIndex: 'Num'
}]
});
})
Opening the grid in a window on button click
var grid = Ext.getCmp('testgrid');
var win = Ext.create('Ext.Window', {
title: 'Grid Filters Example',
height: 400,
width: 700,
modal: true,
layout: 'fit',
items: grid
}).show();
grid.getStore().load();
Just couldnt figure out what I am doing wrong. Appreciate any help in fixing this issue.
Is there any reason to fetch all the data from server?
I'd recommend using data paging with all the pros, speed being the first one (and some cons too). If you choose to use an infinite grid, it will work well. In fact the basic idea behind infinite grid is fetching data in chunks (data paging in other words).
Filtering works without any problems with this scenario, see sample. It's usually handled by server, which is built to do this kind of tasks.

extjs4 with memoryproxy and pagination

I have this very basic example where I use a memoryproxy and pagingmemory toolbar to paginate through data (ideally).
This is extjs working with meteor which sends data directly without the need of a res/ajax/jsonp proxy so I must use memory since the data is already in the client long before extjs has even managed to render it's views.
My problem is that I cannot make the pagination to show a real overview of what's in the store. The refresh is not working and the paginate icons are dead since the pagination sees no items in the store after I load them.
I have a working code example up on jsfiddle: http://jsfiddle.net/rXsVG/5/
Full code example:
Ext.onReady(function(){
Ext.define('User', {
extend: 'Ext.data.Model',
fields: [
{name: 'id', type: 'int'},
{name: 'name', type: 'string'}
]
});
var store = new Ext.data.Store({
model: 'User',
autoLoad: true,
proxy: {
type: 'pagingmemory',
reader: {
type: 'json'
}
}
});
Ext.create('Ext.grid.Panel', {
height: 500,
width: '100%',
renderTo: 'example-grid',
store: store,
columns: [{
header: 'Name',
dataIndex: 'name',
flex: 1
}],
bbar: {
xtype: 'pagingtoolbar',
pageSize: 10,
store: store,
displayInfo: true
},
listeners: {
afterrender: function(grid, evt) {
console.log('Loading data');
var data = [];
for(var i = 1; i < 20; i++) {
data.push({
id: i,
name: 'Ed Spencer '+i
});
}
// Simulate a really busy server call
setTimeout(function(){
grid.getStore().loadData(data);
}, 500);
}
}
});
});
Also if you hit refresh on the paging toolbar all data will be gone. Any ideas?

Resources