Ext 4.2 Using proxy to save tree - extjs

when I use insertChild() or Sync(), proxy sends GET to server with just _dc param, what I should do to save my tree via proxy?
EDIT:added writer, now ext doing POST but with no data
write listener also didn't call
Ext.define('App.model.FileTree',
{
extend : 'Ext.data.Model',
fields : [
{name : 'id', type: 'string'},
{name : 'name', mapping:'name', type: 'string'},
{name : 'text', type: 'string'},
]
});
Ext.define('App.store.FileTree', {
extend: 'Ext.data.TreeStore',
alias:'filestore',
model : 'App.model.FileTree',
proxy: {
actionMethods: {
create: 'POST',
destroy: 'DELETE',
read: 'GET',
update: 'POST'
},
type: 'ajax',
url : '/app/store/FileTree.php',
reader: {
type: 'json'
},
writer: {
type: 'json',
nameProperty: 'mapping'
}
},
listeners : {
write: function(store, operation, opts){
Ext.each(operation.records, function(record){
if (record.dirty) {
record.commit();
}
});
}
}
});
trying add child like:
var tree = Ext.ComponentQuery.query('filetree')[0];
var record = tree.getSelectionModel().getSelection()[0];
record.appendChild({text:'test',name:'test',id:2,leaf:true});
tree.store.sync();

Configure a writer inside the proxy. Without the writer proxy does not know what to do.
I have a tree in Ext 5.0 (but it works also in Ext 4.x) with tree model configured this way:
Ext.define('At.model.ContinentModel',{
extend:'Ext.data.TreeModel'
,alias:'model.continentmodel'
,idProperty:'id'
,fields:[
{name:'text', type:'string', persist:true}
,{name:'iconColor', type:'string'}
]
,proxy:{
type:'ajax'
,url:'resources/service.php/tree/read/1/'
,writer:{
type:'json'
,allowSingle:false
,encode:true
,rootProperty:'data'
}
}
});
The tree store is configured with autoSync:true. Changes in text field trigger server requests that look like this:

Related

Extjs Store listener

My store function was working efficiently on extjs 6.0, but when migrated to extjs 6.7 its showing error
var store = Ext.create('Ext.data.Store',{
model: 'User',
proxy: {
type: 'ajax',
url : '../ROOT/customHeader/configs/customHeaderConfig.json',
reader:
{
type: 'json',
rootProperty: "custom"
}
},
autoLoad:true,
listeners : {
load : function(thisObj, records){
var logo_src = records[0].get("viewer_logo_src");
panObj.getComponent('header_toolbar').getComponent('headerLogo').setSrc(logo_src);
}
}
});

ExtJS 4 store callback function don't get record

Store callback as follows:
var store = new Ext.create("Ext.data.TreeStore", {
model: "DeptModel",
proxy: {
type: 'ajax',
url: 'jsonWebCommMenuOp_getMenus?PID=0',
reader: 'json'
},
autoload: true
});
store.load({
callback: function(records, options, success) {
var jsonStr = Ext.JSON.encode(records[0].raw);
var jsonObj = Ext.JSON.decode(jsonStr);
alert(jsonStr);
}
});
Server response as follows:
{
"success": true,
"msg": "123"
}
I test callback param success, it is equals to true but records is blank [].
What's the reason? Please help me.
In your case you have to consider following things:
What really is your server response. If it is {"success":true, "msg":"123"}, then you really miss data.
You must set the name of the property which contains the data items in reader config. In ExtJS 4 this can be done with root, in EXTJS 5,6 with rootProperty.
If you load store data by code, set autoLoad to false.
ExtJS 4.2
reader: {
type: 'json',
root: 'data'
}
ExtJS 5 and ExtJS 6
reader: {
type: 'json',
rootProperty: 'data'
}
Notes:
I've reproduced your test case with EXTJS 4.2 and these are the reasons for such a behavior:
JSON response not contains data
root (rootProperty) config is not set.
JSON response contains data, but the name of the property which contains this data is not the same as in reader config.
Working example:
Server response:
{
"success": true,
"data": [
{"text": "Some words"},
{"text": "Some words"},
{"text":"Some words"}
]
}
HTML:
Ext.define('DeptModel', {
extend: 'Ext.data.Model',
fields: [
{name: 'text', type: 'string'}
]
});
Ext.onReady(function(){
var store = new Ext.create("Ext.data.TreeStore", {
model: "DeptModel",
proxy: {
type: 'ajax',
//url: 'jsonWebCommMenuOp_getMenus?PID=0',
// I've used simple PHP script to populate JSON response:
url: 'store-load.php',
reader: {
type: 'json',
root: 'data'
}
},
autoLoad: false
});
store.load(
{
callback: function(records, options, success)
{
//var jsonStr = Ext.JSON.encode(records[0].raw);
//var jsonObj = Ext.JSON.decode(jsonStr);
//alert(jsonStr);
console.log(records);
}
});
});
There are some points below which are you need to recheck with your code:-
autoLoad instead of autoload.
With TreeStore you should mention root: {}
Have a look at this working fiddle.
Note: I am using data.json to request.
Hope this will help/guide you properly.

ExtJs-> Ext.Store.proxy.writer error: No type specified for writer.create

So I have upgraded from extjs4 to extjs6 and this store always have this error:
No type specified for writer.create
This code has two uses:
For getting the data for the initial page
For getting the data for whenever a button is clicked.
Whenever I comment out the proxy.writer code portion, it will produce the data for the initial page.
But whenever I won't comment it out, it will not get the data for the initial page.
And it will also return this error whenever I clicked a button:
Uncaught TypeError: items.slice is not a function
So my question is, is the writer portion have wrong syntax or something since it is updated to extjs6?
P.S. I tried to change the
this.callOverridden to this.callParent since it states that the this.callOverridden is already deprecated, still has the same error.
Ext.define('Stm.store.stmpdate', {
extend: 'Extends.data.Store',
requires: [
'Cstm.Setting',
'Stm.model.stmpdate'
],
model: 'Stm.model.stmpdate',
pageSize: Stm.Const.controller.dataCountLimit,
remoteSort: true,
proxy: {
type: 'ajax',
url: Cstm.Setting.getEntryUrl() + '/stm/stm-update/stm-update',
reader: {
type: 'json',
rootProperty: 'data'
},
writer: Ext.data.writer.Json.override({
getRecordData: function() {
var data = this.callOverridden(arguments);
var record = arguments[0];
if ( record.associations.length > 0 ) {
Ext.Array.each(record.associations.keys, function(key) {
data[key] = [];
var assocStore = record[key]();
Ext.Array.each(assocStore.data.items, function(assocItem) {
data[key].push(assocItem.data);
});
});
}
return data;
}
}),
api: {
create: Cstm.Setting.getEntryUrl() + '/stm/stm-update/application',
update: Cstm.Setting.getEntryUrl() + '/stm/stm-update/approval'
},
actionMethods: {
create: 'POST',
read: 'POST',
update: 'POST',
destroy: 'POST'
}
},
sorters: [
{property: 'aplDatetime', direction: 'DESC'},
{property: 'siteDomain', direction: 'ASC'},
{property: 'pageName', direction: 'ASC'}
]
});
Model:
Ext.define('Stm.model.stmpdate', {
extend: 'Ext.data.Model',
fields: [
{name: 'siteId', type: 'integer'},
{name: 'siteName', type: 'string'},
{name: 'siteUrl', type: 'string'},
{name: 'tmpId', type: 'integer', defaultValue: 1},
{name: 'updType', type: 'string'}
],
hasMany: [{
model: 'Stm.model.ServerInfo',
name: 'servers',
associationKey: 'servers',
reference: 'tmpId'
}]
});
Yes, you are using override in a way that may have worked in ExtJS 4 but is AFAIK unsupported across all versions of ExtJS.
What you want to do is define your custom writer as a new class:
Ext.define('MyApp.app.data.MyCustomJsonWriter', {
extend: 'Ext.data.writer.Json',
alias: 'writer.mycustomjson',
getRecordData: function() {
var data = this.callParent(arguments);
var record = arguments[0];
if ( record.associations.length > 0 ) {
Ext.Array.each(record.associations.keys, function(key) {
data[key] = [];
var assocStore = record[key]();
Ext.Array.each(assocStore.data.items, function(assocItem) {
data[key].push(assocItem.data);
});
});
}
return data;
}
});
require that class from your store:
requires: [
'MyApp.app.data.MyCustomJsonWriter'
]
and then instantiate it by alias:
writer: {
type: 'mycustomjson'
}

Accessing a store from another store - Sencha Touch

I'm trying to create a store and inside access the data from another store to construct the proxy url.
Something like this:
Ext.define('MyApp.store.Post',{
extend:'Ext.data.Store',
config: {
model: 'MyApp.model.Post',
proxy: {
type: 'ajax',
url: 'http://mywebsite.com/get?userid=' + Ext.getStore('UserData').getAt(0).data.userid,
reader: {
type: 'json'
}
}
}
});
So, I'm basically trying to get the userid from another store to be able to construct the correct url.
This doesn't work, I get:
Uncaught TypeError: Object #<Object> has no method 'getStore'
What is the correct way to do this?
EDIT: Okay I put in a dummy URL and trying to change it with a listener, this is my store now:
Ext.define('MyApp.store.Post',{ extend:'Ext.data.Store',
config: {
fields: [
'title', 'link', 'author', 'contentSnippet', 'content'
],
proxy: {
type: 'jsonp',
url: 'https://ajax.googleapis.com/ajax/services/feed/load?v=1.0&q=http://feeds.feedburner.com/SenchaBlog',
reader: {
type: 'json',
rootProperty: 'responseData.feed.entries'
}
},
listeners: [
{
beforeload: function(){
console.log("store loaded"); //I DON'T SEE THIS IN CONSOLE
return true;
}
}
]
},
});
Basically you did nothing wrong, but the reason is sencha touch uses asynchronous loading and it seems that Ext.getStore() is not instantiated at the time your store is defined.
Let's try this method instead:
First, add a listener for beforeload event inside your store config:
Ext.define('MyApp.store.Post',{
extend:'Ext.data.Store',
config: {
model: 'MyApp.model.Post',
proxy: {
type: 'ajax',
//url: you don't even need to set url config here, simply ignore it
reader: {
type: 'json'
}
}
},
listeners: [
{
fn: 'setUrl',
event: 'beforeload'
}
]
});
then declare a function like this, in the same file:
setUrl: function(){
this.getProxy().setUrl(Ext.getStore('UserData').getAt(0).data.userid);
return true;
}
This way, it's ensured to set the url for your store's proxy right before it's loaded. And basically at the time, all core methods are instantiated.
Update: please try this with your Post store:
Ext.define('MyApp.store.Post',{
extend:'Ext.data.Store',
config: {
//autoLoad: true,
fields: ['title', 'link', 'author', 'contentSnippet', 'content'],
proxy: {
type: 'jsonp',
url: 'dummy url',
reader: {
type: 'json',
rootProperty: 'responseData.feed.entries'
}
},
},
initialize: function(){
console.log("loaded!");
this.getProxy().setUrl('https://ajax.googleapis.com/ajax/services/feed/load?v=1.0&q=http://feeds.feedburner.com/SenchaBlog');
//return true;
}
});
After reading the source code of the pull-to-refresh plugin, I see that Sencha Touch use an Ext.data.Operation instead of Ext.data.Store.load() function. So you will have to put it into the initialize method instead.
Use Ext.data.StoreManager.lookup('UserData') to get the store instance.
But in your case, I would use this somewhere, where you work with the userid:
var postsStoreInstance = ...;
postsStoreInstancegetProxy()._extraParams.userid = userid;
It adds a query paremetry to the store's proxy url
The way you do it is the correct way. What is the code of your store definition?
Make sure your store has storeId: 'UserData'.
See this working example:
Ext.define('User', {
extend: 'Ext.data.Model',
fields: [
{name: 'id'}
]
});
Ext.create( 'Ext.data.Store', {
model: 'User',
storeId: 'UserData'
});
Ext.define('MyApp.store.Post',{
extend:'Ext.data.Store',
config: {
model: 'MyApp.model.Post',
proxy: {
type: 'ajax',
url: 'http://mywebsite.com/get?userid=' + Ext.getStore('UserData'),
reader: {
type: 'json'
}
}
}
});

Sencha Touch 2 association problems

I get from server next JSON:
{
"contextPath":"http://apps.dhis2.org/demo",
"user":{
"id":"GOLswS44mh8",
"name":"System Administrator",
"isAdmin":true,
"ou":{
"id":"ImspTQPwCqd",
"name":"Sierra Leone"
}
}
}
I need convert this JSON in two Models : User model and OrganizationUnit model.
I read this tutorial http://docs.sencha.com/touch/2.2.1/#!/api/Ext.data.reader.Reader so it my code :
User model :
Ext.define('mobile-visualizer.model.User', {
extend: 'Ext.data.Model',
config: {
fields: [
{name: 'id', type: 'string'},
{name: 'name', type: 'string'},
{name: 'isAdmin', type: 'boolean'}
],
hasOne: {
model: "mobile-visualizer.model.OrganizationUnit",
name: "ou"
},
proxy: {
type: 'ajax',
url : 'http://apps.dhis2.org/demo/dhis-web-visualizer/initialize.action',
method : 'GET',
withCredentials : true,
useDefaultXhrHeader : false,
reader: {
type: 'json',
rootProperty: 'user'
}
}
}
});
OrganizationUnit model :
Ext.define('mobile-visualizer.model.OrganizationUnit', {
extend: 'Ext.data.Model',
config: {
fields: [
{name: 'id', type: 'string'},
{name: 'name', type: 'string'}
],
belongsTo: 'mobile-visualizer.model.User'
}
});
Store :
Ext.define('mobile-visualizer.store.UsersStore', {
extend : 'Ext.data.Store',
model : "mobile-visualizer.model.User",
autoLoad : false,
storeId : "usersStore",
proxy : {
type : 'ajax',
url : 'http://apps.dhis2.org/demo/dhis-web-visualizer/initialize.action',
method : 'GET',
withCredentials : true,
useDefaultXhrHeader : false,
reader : {
type : 'json',
rootProperty : 'user'
}
}
});
So, when I try get user from store using another code :
var store = Ext.create('mobile-visualizer.store.UsersStore');
store.load({
callback : function() {
// the user that was loaded
var user = store.first();
console.log(user.ou())
}
});
I have error : Uncaught TypeError: Object [object Object] has no method 'ou'
I can get all information about user but I can't get ou from user. It look like some association issue.
But I make all as like official tutorial . Please help to resolve this problem.
Thanks.
Follow my rules and everything will come out rosy:
http://extjs-tutorials.blogspot.ca/2012/05/extjs-hasmany-relationships-rules.html
http://extjs-tutorials.blogspot.ca/2012/05/extjs-belongsto-association-rules.html
These are for extjs, but very similar for sencha touch.
You are forgetting the associationKey.
Also, no need to redefine proxy in store as it will inherit its model's proxy.
Also, a user probably belongs to an org unit and doesn't have one...

Resources