Unanswered: store ajax serving multi read requests (best practice question)
Hi, im trying to understand the proper design concept of Store proxies using the Ajax api config and have a question on how this should be done.
suppose i have a store which has a server proxy using the Ext.data.proxy.Ajax class and i have an api with the following:
proxy: {
type: 'ajax',
api: {
read: 'some/something/list.json',
create: 'some/something/insert.json',
update: 'some/something/update.json',
destroy: 'some/something/destroy.json'
}
}
now suppose my read is triggered by a search button and when i have a blank text box and click search it makes a request through the read api to retrieve the list.json. but i want to have another read as part of the same store / api to read individual records say something like this:
read: 'some/something/<field_value>.json'
my proxy read is already assigned to the list.json but i want to allow the same store proxy to be able to read from individual record searches also. granted that i cant have two read statements in my proxy. how would I go about writing this?
help me understand? maybe my server controller has to be able to determine by keyword #PathVariable if path is list i.e .json then call the list db query otherwise if .json then run the individual search query through the db.?? and if so what would be the read: url?
whats the best way to design and build this?
Thanks in advance
If you want to read single record instead of defining proxy in store you should do it in Model and then call load on model itself something like below.
Ext.define('app.model.User', {
{
fields: [
{ name: 'LoginUserId', type: 'string' },
{ name: 'FirstName', type: 'string' },
{ name: 'LastName', type: 'string' }],
proxy:
{
type: 'rest',
url: '/User',
reader:
{
type: 'json',
root: ''
}
}
});
var user = Ext.ModelMgr.getModel('app.model.User');
user.load(123, {
success: function(userObj) {
}
});
Related
I am learning ExtJS framework, for experiments I use on front-end side ExtJS and on back-end side JavaEE Spring framework (it is configured like as REST service). So, I start my front-end part on localhost:1841 and back-end part on localhost:8080. Question is:
How I can say to ExtJS.Store that requests need to send to
localhost:8080/** instead of localhost:1841/**?
Sorry for my English!
In ExtJS have singleton you can use this class.
Singleton pattern is a design pattern which restricts instantiation of a class to only one object. This is useful when exactly one object is needed across the system. The Singleton pattern provides a single point of access to a particular instance. Implementation of a singleton pattern must satisfy the single instance and global access principles.
For this "How I can say to ExtJS.Store that requests need to send to localhost:8080/** instead of localhost:1841/**?"
You can use in your app like below code :
Firstly create singletone class
/*
* Create singletone class in your application
* This class you can access in your application anywhere you want within the app.
* Usage:
* commonUtility.getServerUrl();// whatever property you have defined inside of config you can access like this
*/
Ext.define('APPNAME.utils.SingleToneClassName', {
alternateClassName: 'commonUtility',
singleton: true,
config: {
/*
* you can put local or live also or whatever you want.
* for local it will be ip address like this {'http://192.168.30.83:8080/'}
* for live is will be live tomcate host url {http://example.com/}
*/
serverURL: 'http://192.168.30.83:8080/'
},
constructor: function(config) {
var me = this;
me.initConfig(config);
},
});
Create/Define your store
//Your store
Ext.define('APPNAME.store.StoreName', {
extend: 'Ext.data.Store',
fields: ['your fields here'],
storeId: 'storeIdHere',
alias: "store.storeAliasHere",
proxy: {
type: 'ajax',
url: commonUtility.getServerUrl() + 'your Server Method name here', //Based on your server URL acceptance
withCredentials: true,
reader: {
type: 'json',
rootProperty: 'data',
keepRawData: true
}
},
autoLoad: true, //If you need auto load then put true otherwise false
listeners: {
beforeload: function(store, operation, options) {
//If you have token based authenthication then you need to put like below
store.getProxy().setHeaders({
"x-auth-token": 'your token here'
});
//If you have need to pass some parameter in API method then you can pass like below
store.getProxy().extraParams.your_parameter_name = 'value';
}
},
});
//If you want to load your store on some event or any other functions
//then
Ext.getStore('your_storeId_herer').load({
url: commonUtility.getServerUrl() + 'your Server Method name here', //Based on your server URL acceptance
params: {
//If you have need to pass some params in server side then
//you put here like
name: 'value'
}
});
I hope this will help you. for more details you can refer ExtJS6.x Docs
i need to implement the multisort in grid that populate from a Ajax Store, but i have also a problem with the simple sorting of column.
This is my store:
dsUser = Ext.create('Ext.data.Store', {
model: 'user',
pageSize: defPagSize,
totalProperty: 'totalCount',
autoLoad: {start: 0, limit: defPagSize},
remoteSort: true,
proxy: {
type: 'ajax',
enablePaging:true,
url: '<c:url value="/queryForList.action?query=User.getUsers"/>',
reader: {
type: 'json',
root: 'list',
totalProperty:'totalCount'
}
}
});
Anytype of help is usefull.
Thanks.
EDIT:
Now i re-write the old logic of sorting in my application..At this moment i find anyone can help me to post and modify grid for posting an array of (property:'', direction:'') and mantain the icon on the grid to select. (sorry for my english)
The proxy is merely sending through the sortParam and value in a structure that is usable in JS...e.g., a JSON-encoded array of objects ([{"property":"email","direction":"DESC"}]).
When you receive this request server-side, you'll absolutely need top parse apart the sort order object and convert it to a string that your DB can understand. Using the raw value from the query string in your DB will not work, nor was it intended to work like that.
When I do this, it's typically like this:
Receive request
Search for sort order param in query string
Decode the JSON string into an object in my server-side app's language
Iterate over the array of sorters and build a "sort" string
Send parsed sort string along to the DB query
I am using this to get the result from server
controller.allVisitStore = new Ext.data.Store({
model: 'allVisit',
autoLoad : true,
proxy: {
type: 'ajax',
id: 'allvisit_app_localstore',
url: '/RadMobApp/api',
extraParams:{
action:'query',
queryName:'GET_ALL_VISIT',
authToken: localStorage.getItem("auth_token"),
patTicketId: localStorage.getItem("patientId"),
retFormat:'XML',
keyValuePair:'yes'
},
// the return will be XML, so lets set up a reader
reader: new Ext.data.XmlReader({
// records will have an "T4" tag
record: 'data'
})
}
});
but i am not getting any thing.But i formed this url in browser and checked this i got the correct result. now here i want to check is there any problem in the url formation.How to check the url formation with extra parameter which is pass through ajax. I have checked in Inspect element-> network -> api there is no any api request found there.Is anything wrong in my code. Thanks in advance...
Use Firebug for Firefox or Chrome's developer tools to see what's going on when that store attempts to load itself. My hunch is that your url is incorrect and should be url: '/api' because RadMobApp is probably your app root.
I'm having a problem with loading a Sencha store. My store declaration is like this:
Ext.regModel('Car',{
idProperty: 'id',
fields: [
//'id', 'company', 'driver', 'carType','xCoordinate','yCoordinate'
{name: 'id', type: 'int'},
{name:'company', type:'string'} ,
{name:'driver', type:'string'},
{name:'carType', type:'string'},
{name:'xCoordinate', type:'int'},
{name:'yCoordinate', type:'int'}
]
});
var strr= new Ext.regStore({
id:'carStore',
model:'Car', //configuration option is the cars
proxy: {
type: 'ajax',
url: 'http://localhost:8080/A/carStore.html&callback=?',
reader: {
type: 'json',
root: 'carss'
},
},
autoLoad: true
});
And I'm keeping the store in a list:
CarManagementSystem.views.carList = new Ext.List({
id: 'carList',
store: 'carStore',
onItemDisclosure: function (record) {
var selectedCar = record;
CarManagementSystem.views.addNewCar.load(selectedCar);
CarManagementSystem.views.viewport.setActiveItem('addNewCar', { type: 'slide', direction: 'left' });
},
itemTpl: '<div class="list-item-id">{id}</div>' +'<div class="list-item-driver">{driver}</div>'
});
However, when I try to load the list with my JSON file, I get this error:
XMLHttpRequest cannot load http://localhost:8080/A/carStore.html&callback=?&_dc=1311751412006&limit=25. Origin null is not allowed by Access-Control-Allow-Origin.
sencha-touch-debug.js:7212
Uncaught TypeError: Cannot read property 'length' of undefined
I'm keeping my JSON file in an html format and it is kept in the server. I'd appreciate any help.
Thanks!
You are encountering the classic CORS issue.
It's a browser security, called web-security. If you are in dev mode, you can run Chrome and disabling this flag. But if you run your app in production on a browser, you will need to bypass this ajax specification restriction.
To bypass it, you can use proxys (such as creating a back-end script on the same domain will load for you the resource) or you can use JSON-P. For this you will need to change your store to a script tag BUT ALSO you will need the server to be able to detect a callback param and send it to you as a JS function automatically executed when inserted in the DOM.
I will add that you won't have this issue when running in Phonegap because PhoneGap is not running a web server but serves files with the file:// protocol.
If you want to learn more, and I recommand as it is a common pb when developing mobile web apps, you should learn what JSON-P is, what CORS is, and how it works.
You can't hit a port number (8080) when making an AJAX request. If you end up needing a cross-domain request change your proxy type to 'scripttag'.
You should change the proxy type from 'ajax' to 'type: 'scripttag'
Ok, I am semi-new to ExtJS, and I am building a program that has "inputs" that are listed in a grid, and in my DB these inputs can be linked to "symptoms".
I am trying to create a function that will take in the id of the input and grab all of the symptoms from the database that are linked to that symptom, and list them in a field set.
It works fine when I click on an input that is only linked to one symptom, but if the input is linked to more than one symptom, then the error says.. "invalid property id"
This is what I have for my function.
function listSymptoms(inputID){
Ext.Ajax.request({
url: "../../inc/project4.php?list=symptoms",
reader: new (Ext.data.JsonReader)({
root: "symptoms",
inputid: "id"
}),
params: {
inputid: inputID
},
method: "POST",
success: function (f, a){
var jsonData = Ext.util.JSON.decode(f.responseText);
symptomsFieldSet.body.update(jsonData.data.name);
},
failure: function (f,a){
Ext.Msg.alert('There was a problem opening your message.');
}
});
}
I have the inputID for the function being passed in when the user clicks on one of the inputs that are held inside the grid.
I believe that my problem has something to do with this line..
symptomsFieldSet.body.update(jsonData.data.name);
I am just stumped on how to handle this. Do I need to create a data store like I have for grids? Or is there an easier way to do this?
ANY help is appreciated! thanks in advance.
I think you need to rethink the structure of your JSON response object. You can send this in your JSON response to your request. If you are using Ext.util.Ajax calls instad of a form, you'll need to decode this JSON response string using the util method Ext.util.JSON.decode(). Check out the API Documentation
{
success: true,
msg: {text: 'this can be used for error message handling' },
data : [
{id:1,
chiefComplaint: 'head hurts',
symptoms: [
{symptomID: '740.1', text: 'Headache'},
{symptomID: '12352135'. text: 'and so on'}
}
]
]
}