Slow loading of combobox items with viewmodel - javascript

My app has a form with three combobox.
The comboboxs stores are in a ViewModel.
Ext.define('app.ComboboxsModel', {
extend: 'Ext.app.ViewModel',
alias: 'viewmodel.comboboxsmodel',
stores: {
storeA:{
model:'AModel',
autoLoad:true,
actionMethods:{
read:'POST'
},
proxy: {
type: 'ajax',
url: 'php/url',
reader:{
type:'json',
rootProperty: 'data',
successProperty: 'success'
}
}
},
storeB:{
model:'BModel',
autoLoad:true,
actionMethods:{
read:'POST'
},
proxy: {
type: 'ajax',
url: 'php/url',
reader:{
type:'json',
rootProperty: 'data',
successProperty: 'success'
}
}
},
storeC:{
...
}
});
It works. The data is loaded into comboboxs.
The problem is that the loading is very slow.
Data from the last combobox take about 5 seconds to load.
If instead of declaring the stores in viewmodel I placed the stores in the app store folder and reference them in Apllication.js file works as expected and faster.
However, I intended to use ViewModel.
Is there any way to load faster - or before load form - the stores (comboboxs items) with viewmodel?
EDIT:
Comboboxs Fiddle: https://fiddle.sencha.com/#fiddle/vqe
COMMENT:
Explain better the issue:
The problem is not at this stage, but when I edit a record in a grid and I want to load the record data in the form comboboxs (config 'name').
If the config valudeField 'name_id' is replaced by 'name' load faster, but still slow.
However, on the server side (PHP), for the comboboxs, I work preferably with ids (primary key).
name: 'name',
displayField: 'name',
valueField: 'name_id',

Related

EXTJS Extending Ext.data.JsonStore

I'm an ExtJS (I'm using version 5.1) newbie and I'm trying to split a monolithic single file application in different files. I've moved a store outside in a separate file. This is the store in the separate file:
Ext.define("MT.store.MicroProfilerStore", {
extend: "Ext.data.JsonStore",
singleton : true,
model : 'MT.model.MicroProfilerModel',
storeId: "micro_profiler_store",
autoLoad: false,
proxy: {
type: 'ajax',
url: './backend/profiler.php',
reader: {
type: 'json',
rootProperty: 'answers'
}
}
});
If I use this file the ajax request is correct and I can see the reply but it looks like the store is ignoring the rootProperty and instead of having the array of answers in the store.getData() I have a single item array with the first value that is the entire response converted to javascript like:
[{success: 'true', answers: [{}, {}]}]
But If I create the store directly without subclassing using Ext.create("Ext.data.JsonStore", {...}) it's working!
The hack that I've found after a day of trying that allows me to keep a separate file for the store is this:
Ext.define("MT.store.MicroProfilerStore", function(){
Ext.require(['MT.model.MicroProfilerModel'], function(){
Ext.create("Ext.data.JsonStore", {
singleton : true,
model : 'MT.model.MicroProfilerModel',
storeId: "micro_profiler_store",
autoLoad: false,
proxy: {
type: 'ajax',
url: './backend/profiler.php',
reader: {
type: 'json',
rootProperty: 'answers'
}
}
});
});
return {};
});
Then I can get the store using StoreManger.lookup(). Ok it's working fine but the question is why ?
PS
I've already tried preloading the model before the store, explicity requiring the model and the store in many place It doesn't looks like a precedence error
Thanks for your help
We have many stores which could be made singleton, but it seems that singleton:true isn't part of ExtJS best practices.
If we need a "singleton store", which is like 90% of the time, we still make a normal store, but add that store to the stores array in Application.js, so that the instance is created before Application launch. What makes the store a singleton is a storeId, by which it is referenced from everywhere. All our singleton stores are defined using a special constructor/callParent construction, because we didn't get reader rootProperty to work otherwise:
Ext.define('MyApp.store.Directories',{
extend: 'Ext.data.Store',
storeId: 'DirectoryStore',
constructor: function() {
var me = this;
this.callParent([{
proxy: {
type: 'ajax',
headers:{'Accept':'application/json'},
noCache: true,
pageParam: false,
startParam: false,
limitParam: false,
extraParams: {
q: 'directory'
},
url: '../api/AddressBook',
reader: {
type: 'json',
rootProperty: 'data'
}
},
autoLoad: true
}]);
}
});
The special constructor/callParent part makes the difference here. We don't exactly know WHY it works, but it works - we copied that approach from Sencha Architect-generated code. If we now need that store's content anywhere, we do as follows:
xtype:'combo',
name:'Directory',
store:'DirectoryStore' // <- reference by storeId!
The storeId reference fails if we don't add the store to the stores array in Application.js, where we should keep a list of all "singleton" stores:
Ext.define('MyApp.Application', {
extend: 'Ext.app.Application',
name: 'MyApp',
views: [
/* Allgemein */
...
],
controllers: [
'Configuration',
...
],
stores: [
'Directories',
...
]

Extjs 5.0 model POST values not received on server side (working Extjs 4.2)

I am upgrading our Extjs 4.2 app to Extjs 5.0.
I am able to bring up all the read only pages but i am getting issues when i try to update/save the data. I will really appreciate your help!!
My model data values are not showing up on the server side, i am able to print model with console.log(model) and it has all the values , but on the server side it only has id and all the other parameters are showing as null.
Here is proxy in the model :
Ext.define('MyApp.model.User', {
extend: 'Ext.data.Model',
id: 'user',
proxy: {
type: 'rest',
url : '/rest/update/user',
listeners: {
exception: function(proxy, response, operation) {
Ext.Msg.alert('Failed', 'Save the user Failed!');
}
}
},
fields: [
{name: 'id', type: 'int'},
{name: 'userName', type: 'string'},
{name: 'country', type: 'string'}
]
}
The controller :
onUserUpdateAction: function(button, event, action) {
var model = Ext.create('MyApp.model.User');
model.set('id', "123");
model.set('userName', "john");
model.set('country', "usa");
---
model.commit() / without commit() it does not add the id in URL like /user/123
model.save();
}
Here is the server side code :
#PUT
#Consumes({ "application/json" })
#Path("/Update/user/{id}")
updateUser(#PathParam("id") final int id, final User record);
First line log in the implementation class, id is there but all the other values are null
*** In updateUser() method, id : 123, record: User(id=123, **userName=null, country=null**)
The problem here is that you try to fool the Ext. You create new record with id - normally ids are assigned by the server. Therefore, you need to commit it to clear it phantom (new record) flag, so that Ext thinks it is already existing record. But, after commit, the record has no modified fields and, by default, only modified fields are sent to the server. Therefore, you need a writer configured, something like this:
Ext.define('MyApp.model.User', {
extend: 'Ext.data.Model',
idProperty: 'id',
fields: [
{name: 'id', type: 'int'},
{name: 'userName', type: 'string'},
{name: 'country', type: 'string'}
],
proxy: {
type: 'rest',
url : 'success.php',
listeners: {
exception: function(proxy, response, operation) {
Ext.Msg.alert('Failed', 'Save the user Failed!');
}
}
,writer:{
type:'json'
,writeAllFields:true
}
}
});

Initializing a store's data in Extjs

I have store that I would like to initialize from a database but I couldn't find a standard init method for the Ext.data.Store. I found a couple of examples with the StoreManager component, but I think that's not what I'm looking for. I have an MVC structure for my app and I'd like to keep it, I only want to initialize my store's data field using a method I define. Could someone explain how to do so?
I either understand you wrong or your question is straight forward. You configure a store with a model like this. That's all. You may just chose a provider(reader/writer) that fit your needs.
// Set up a model to use in our Store
Ext.define('User', {
extend: 'Ext.data.Model',
fields: [
{name: 'firstName', type: 'string'},
{name: 'lastName', type: 'string'},
{name: 'age', type: 'int'},
{name: 'eyeColor', type: 'string'}
]
});
Ext.define('YourMVCNameSpace.data.UserStore', {
extend: 'Ext.data.Store',
constructor: function (config) {
config = Ext.Object.merge({}, config);
var me = this;
// do what you need with the given config object (even deletes) before passing it to the parent contructor
me.callParent([config]);
// use me forth on cause the config object is now fully applied
},
model: 'User',
proxy: {
type: 'ajax',
url: '/users.json',
reader: {
type: 'json',
root: 'users'
}
},
autoLoad: true
});
Note that the reader will expect a Json result like this:
{"total": 55, "users":["...modeldata.."]}
and is referring to a url like
http://localhost/YourAppDomain//users.json
Place the store as 'User' within the controller store array and retrieve it within the Controller by calling getUserStore() or directly from the Ext.StoreMgr using Ext.StoreMgr.lookup('User');
Note that by convention the Controller (MVC) will override any storeId you set on the store and will just use the name.

List not populating with a JsonP proxy

I want to have a Navigation view. I am trying to populate the list in Sencha Touch using a JsonP proxy.
Here's the sample code snippet of what I have tried till now :
var view = Ext.define('MyApp.view.NavigateView', {
extend: 'Ext.navigation.View',
xtype:'navigateview',
config : {
fullscreen:true,
styleHtmlContent:true,
scrollable:true,
items : [
{
title:'Navigation',
items : [
{
xtype:'list',
store: {
fields : ['title','author'],
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'
}
},
autoLoad:true,
},
itemTpl:'<div class="contact">{title} <strong>{author}</strong></div>',
listeners : {
itemtap : function(){
Ext.Msg.alert('Called');
}
}
}
],
}
]
}
});
But the problem is, my list is not getting populated. No items are being shown up in the list.
Also, I am constantly getting this error on console.
XMLHttpRequest cannot load
http://api.tinyhippos.com/xhr_proxy?tinyhippos_apikey=ABC&tinyhippos_rurl=list.php%3F_dc%3D1334462633038%26page%3D1%26start%3D0%26limit%3D25.
Origin http://localhost is not allowed by Access-Control-Allow-Origin.
Anyone please guide ? Anything that I am missing here ?
i was facing the same error when using AJAX request in cross domain.
have a look here
you have to make sure that the server part is configured properly using jsonp
as a first step identify if your application will run correctly when you disable web security in your browser
locate your chrome installation directory
then type in your cmd: chrome --disable-web-security
Your Ext.navigation.View object is containing one Ext.Component object (xtype not defined so defaulted to 'component') that is containing your list. If you put your list directly as an item of your view, it'll be rendered:
var view = Ext.define('MyApp.view.NavigateView', {
extend: 'Ext.navigation.View',
xtype: 'navigateview',
config : {
fullscreen: true,
styleHtmlContent: true,
scrollable: true,
items : [{
title: 'Navigation',
xtype: 'list',
store: {
fields: ['title','author'],
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'
}
},
autoLoad:true
},
itemTpl: '<div class="contact">{title} <strong>{author}</strong></div>'
}]
}
});
Note1: Not sure why your code is not working.
Note2: The error your mentioned is not related to your code snippet

How to get data from extjs 4 store

Im stack with ext js 4 at the very beginning. Im trying to get the current user data when starting the application using store. But Im not getting any data from the store, even the store.count return 0.
I found many description how to create store, but not how to access the data in it. I managed to get the data using Ext ajax request, but i think would be better using store and i cant avoid them..
My model:
Ext.define('MyApp.model.User', {
extend: 'Ext.data.Model',
fields: [
'id',
'username',
'email'
]
});
My store looks like:
Ext.define('MyApp.store.User.CurrentUser', {
extend: 'Ext.data.Store',
requires: 'MyApp.model.User',
model: 'MyApp.model.User',
autoLoad: true,
proxy: {
type: 'ajax',
method: 'POST',
url: Routing.generate('admin_profile'),
reader: {
type: 'json',
root: 'user'
}
}
});
The returned json:
{
"success":true,
"user":[{
"id":1,
"username":"r00t",
"email":"root#root.root"
}]
}
And the application:
Ext.application({
name: 'MyApp',
appFolder: '/bundles/myadmin/js/app',
models: ['MyApp.model.User'],
stores: ['MyApp.store.User.CurrentUser'],
//autoCreateViewport: true,
launch: function() {
var currentUser=Ext.create('MyApp.store.User.CurrentUser',{});
/*
Ext.Ajax.request({
url : Routing.generate('admin_profile'),
method: 'POST',
success: function(resp) {
var options = Ext.decode(resp.responseText).user;
Ext.each(options, function(op) {
var user = Ext.create('MyApp.model.User',{id: op.id,username:op.username,email:op.email});
setUser(user);
}
)}
});
*/
currentUser.load();
alert(currentUser.count());
}
});
The problem itself isn't that the store does not contain data, the problem is that the store load is asyncronous therefore when you count the store records, the store is actualy empty.
To 'fix' this, use the callback method of the store load.
currentUser.load({
scope : this,
callback: function(records, operation, success) {
//here the store has been loaded so you can use what functions you like
currentUser.count();
}
});
All the sencha examples have the proxies in the store, but you should actually put the proxy in the model, so that you can use the model.load method. the store inherits the model's proxy, and it all works as expected.
it looks like model.load hardcodes the id though (instead of using idProperty), and it always has to be an int, as far as I can tell.
good luck!

Categories

Resources