Here is the super class:
Ext.define('My.store.Direct', {
extend: 'Ext.store.Direct',
paramsAsHash: true,
proxy: {
reader: {
type: 'json',
root: 'data',
totalProperty: 'total'
},
type: 'direct',
}
});
In subclasses I only need to set the API config. I tried:
Ext.define('My.store.User', {
extend: 'My.store.Direct',
model: 'My.model.User',
storeId: 'user',
constructor: function () {
this.callParent(arguments);
this.getProxy().api.read = RPC.UserApi.read;
}}
);
Ext.define('My.store.Post', {
extend: 'My.store.Direct',
model: 'Mehr.model.Post',
storeId: 'post',
constructor: function () {
this.callParent(arguments);
this.getProxy().api.read = RPC.PostApi.read;
}}
);
Unfortunately, after executing the code both store will have the api.read of the first subclass. What is wrong with it? What is proper method of extending stroes?
Create your proxy in constructor, otherwise proxy goes to the prototype of My.store.Direct and because it is an object, not a primitive type (int, string, bool), it is accessed by reference. Thus, changing proxy in one instance changes all instances - there is only one proxy in fact.
So base class should be defined similar to this
Ext.define('My.store.Direct', {
extend: 'Ext.data.DirectStore',
paramsAsHash: true,
constructor:function(config) {
Ext.merge(config, {proxy: {
reader: {
type: 'json',
root: 'data',
totalProperty: 'total'
},
type: 'direct'
}
});
this.callParent([config]);
}
});
Related
I have a grid with dynamic columns:
MODEL
Ext.define('App.mdlCriteriosConcurso', {
extend: 'Ext.data.Model',
fields: [
]
});
STORE
Ext.define('App.strCriteriosConcurso', {
extend: 'Ext.data.Store',
model: 'App.mdlCriteriosConcurso',
autoLoad: false,
proxy: {
type: 'ajax',
api: {
read: 'some url',
update: 'some url',
},
reader: {
type: 'json',
root: 'data',
totalProperty: 'total'
},
writer: {
root: 'records',
encode: true,
writeAllFields: true
}
}
});
GRID
var almacenCriteriosConcurso = Ext.create('App.strCriteriosConcurso');
//Some code ...
{
xtype:'grid',
itemId:'gridCriteriosConcursoV4',
store:almacenCriteriosConcurso,
plugins: [Ext.create('Ext.grid.plugin.CellEditing', {clicksToEdit: 2})],
columns:[]
}
//Some code...
CONTROLLER
Here in the controller I have the next piece of code:
Ext.ComponentQuery.query('viewFichaDetalle #tabpanelsecundario4_1 #gridCriteriosConcursoV4')[0].getStore().addListener('metachange',function(store,meta){
var columnas=0;
var renderer1 = function(v,params,data){
if(v==''){
return '<div style="background-color:#F5FAC3;color:blue;">'+Ext.util.Format.number(0,'0.000,00/i')+'</div>';
}
else{
return '<div style="background-color:#F5FAC3;color:blue;">'+Ext.util.Format.number(v,'0.000,00/i')+'</div>';
}
};
var renderer2 = function(v,params,data){
if(v=='' || v==0){
return '<div style="background-color:#F5FAC3;color:green;">'+Ext.util.Format.number(0,'0.000,00/i')+'</div>';
//return '';
}
else{
return '<div style="background-color:#F5FAC3;color:green;">'+Ext.util.Format.number(v,'0.000,00/i')+'</div>';
}
};
Ext.each(meta.columns,function(col){
if(columnas==2){
meta.columns[columnas].renderer = renderer1;
}
if(columnas>=3){
meta.columns[columnas].renderer = renderer2;
}
columnas++;
},this);
Ext.suspendLayouts();
Ext.ComponentQuery.query('viewFichaDetalle #tabpanelsecundario4_1 #gridCriteriosConcursoV4')[0].reconfigure(store, meta.columns);
Ext.ComponentQuery.query('viewFichaDetalle #tabpanelsecundario4_1 #gridCriteriosConcursoV4')[0].setTitle("<span style='color:red;font-weight:bold;font-size: 12pt'>Criterios del Concurso con ID:</span> "+"<span style='color:black;font-weight:bold;font-size: 12pt'>"+this.IdConcurso+"</span>");
Ext.resumeLayouts(true);
},this);
I create the columns in the php, using the metadata.
With this code I add some renderers to the grid columns. And I see all the data perfect, and can edit the data.
In the php y generate the column and the field like this:
$array_metadata['columns'][]=array("header"=>"<span style='color:blue;'>Resultado</span>","dataIndex"=>"puntos_resultado","width"=>82,"align"=>"right","editor"=>"textfield");
$array_metadata['fields'][]=array("name"=>"puntos_resultado","type"=>"float");
And then pass $array_metadata to 'metaData' response.
But when I try to sync or autosync the store I get this error:
Uncaught TypeError: Cannot read property 'name' of undefined
at constructor.getRecordData (ext-all-dev.js:62247)
at constructor.write (ext-all-dev.js:62192)
at constructor.doRequest (ext-all-dev.js:102306)
at constructor.update (ext-all-dev.js:101753)
at constructor.runOperation (ext-all-dev.js:106842)
at constructor.start (ext-all-dev.js:106769)
at constructor.batch (ext-all-dev.js:62869)
at constructor.sync (ext-all-dev.js:64066)
at constructor.afterEdit (ext-all-dev.js:64162)
at constructor.callStore (ext-all-dev.js:101428)
UPDATE 1
I have fount this thread in Sencha Forums link , and I have tried all posibles solutions and Im getting allways the same error.
The error tells us that you don't fill the model's fields array properly, because that is where name is a required config. In ExtJS 4, you have to add all fields to the model for the sync to work properly.
To be exact, the Model prototype has to be filled with the correct fields before the instances are created.
This means that you will have to override the reader's getResponseData method, because between Ext.decode and readRecords you will have to prepare the model prototype by setting the fields as returned from the server; something like this:
App.mdlCriteriosConcurso.prototype.fields = data.fields;
I have a ViewModel that contains some initial data... this initial data is based off of a global variable that I have created. In the ViewModel, I have a formula that does some logic based on the data set from the global variable. The interesting thing is, this formula does not fire when the ViewModel is created. I'm assuming this is because the Something.Test property does not exist, so the ViewModel internals have some smarts to not fire the method if that property does not exist.
If the property doesn't exist, how do I fire the formula anyway? I know I could look for Something check to see if it has the property Test, but I'm curious why this example wouldn't work. Here's the example:
Ext.application({
name : 'Fiddle',
launch : function() {
// Define global var Something
Ext.define('Something', {
singleton: true
});
Ext.define('MyViewModel', {
extend: 'Ext.app.ViewModel',
alias: 'viewmodel.myView',
data: {
Something: window.Something
},
formulas: {
testSomething: function(getter) {
console.log('here', getter('Something.Test'));
return getter('Something.Test');
},
myTitle: function(getter) {
return 'My Title';
}
}
});
Ext.define('MyView', {
extend: 'Ext.panel.Panel',
bind: {
title: '{myTitle}'
},
viewModel: {
type: 'myView'
}
});
var view = Ext.create('MyView', {
renderTo: Ext.getBody()
});
// This will fire the ViewModel formula
//view.getViewModel().set('Something', window.Something);
console.log(Something, window.Something)
}
});
You can workout some logic to handle when Something.Test is not available, something like:
data: {
Something: window.Something && window.Something.Test || {Test: null}
},
formulas: {
testSomething: function(get) {
var val = get('Something.Test');
console.log('Test');
return val;
},
myTitle: function(getter) {
return 'My Title';
}
}
Hi I am newbie in Backbone and JS.
I need to fetch data from the server and put this value as the default to planProviderMode choice radio button. So i fetch the data in defaultMode variable. But the call is a asynchronous and I receive a value after the planProviderMode: defaultMode.value code has been executed.
var PlanProviderMode = Backbone.Model.extend({
url: '/rest/enrollment/step/plan-provider-mode'
});
var defaultMode = new PlanProviderMode;
defaultMode.fetch({
success: function() {
// recieve correct data
}
});
var formItems = new Backbone.Form({
template: tpl,
className: 'wizard-content',
schema: {
planProviderMode: {
template: formTpl,
type: 'Radio',
options: [
{
label: 'By Plan',
val: 'BY_PLAN',
custom: {
img: '../resources/img/by-plan.jpg'
}
},
{
label: 'By Provider',
val: 'BY_PROVIDER',
custom: {
img: '../resources/img/by-provider.jpg'
}
}
]
}
},
//here i put the default value
data: {
planProviderMode: defaultMode.value
}
});
How could I set the fetched value to the form.
Please let me know if the question is not described well. Thanks.
you should write such code in success callback function which is executed only after the fetch request is completed succesfully.
var PlanProviderMode = Backbone.Model.extend({
url: '/rest/enrollment/step/plan-provider-mode'
});
var defaultMode = new PlanProviderMode;
defaultMode.fetch({
success: function() {
// recieve correct data
//here you put the default value
data: {
planProviderMode: defaultMode.value
}
}
});
var formItems = new Backbone.Form({
template: tpl,
className: 'wizard-content',
schema: {
planProviderMode: {
template: formTpl,
type: 'Radio',
options: [
{
label: 'By Plan',
val: 'BY_PLAN',
custom: {
img: '../resources/img/by-plan.jpg'
}
},
{
label: 'By Provider',
val: 'BY_PROVIDER',
custom: {
img: '../resources/img/by-provider.jpg'
}
}
]
}
}
});
Backnone has a function called "parse" that helps you in this cases.
This function will always be called from backbone before the data from server populate the model.
Take a read in parse method.
There's a answer here.
how to override Backbone's parse function?
Hope it helps
i am trying to load attribute values into an extjs store with the following code:
Ext.define('assert', {
extend: 'Ext.data.Model',
fields: [
{ name: 'id', mapping: '#id' },
{ name: 'test', mapping: '#test' },
{ name: 'name', mapping: '#name' }
]
});
var store = new Ext.data.Store({
model: 'assert',
proxy: {
type: 'ajax',
url : 'App/data/rules.xml',
reader: {
type: 'xml',
model:'assert',
record: 'assert'
}
}
});
but the store always shows up empty.
Heres a blanked out excerpt from the xml file:
<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="****" xmlns:axsl="****" xmlns:sch="*****" xmlns:iso="******" xmlns:xs="*****" xmlns:rule="******">
<title>test Schematron</title>
<pattern name="test Schematron">
<rule context="*****" name="*****">
<assert test="*****" diagnostics="*****" name="*****" id="****" comment="" uval="" source="****"/>
<assert test="******" diagnostics="****" name="****" id="***" comment="" uval="" source="*****"/>
</rule>
</pattern>
</schema>
Im very new to reading XML files to ExtJS, so it would be great if one of you could
show me the proper way to map those attributes.
There's nothing wrong with your XML file. Your problem is that ExtJS stores don't Load data on automatically on creation by default. You have to either enable the autoLoad or load the Store manually with the load function:
Ext.define('assert', {
extend: 'Ext.data.Model',
fields: [
{ name: 'id', mapping: '#id' },
{ name: 'test', mapping: '#test' },
{ name: 'name', mapping: '#name' }
]
});
var store = new Ext.data.Store({
model: 'assert',
autoLoad: true, // The store will start loading as soon as the framework is ready.
listeners: {
load: function(){ // This gets executed when your store is done loading.
console.log('Loaded!!');
}
},
proxy: {
type: 'ajax',
url : 'data/rules.xml',
reader: {
type: 'xml',
model:'assert',
record: 'assert'
}
}
});
Ext.onReady(function(){
console.log('Ready!!');
store.load({ // This works too!
scope: this,
callback: function(records, operation, success) {
console.log('loaded records!!');
}
});
});
Remember that the load is asynchronous and you have to wait until the load is done to be able to use the data!
I recommend that you check the API doc too see all that you can do with the load function.
extjsjavascript
I am trying to acheive i18n for my sencha Ext JS App.
I used the impl from [https://github.com/elmasse/Ext.i18n.Bundle-touch/blob/master/i18n/Bundle.js][1], but with more simplified version.
Basically, I have a store [webUi.util.rb.ResourceBundle] linked to model [webUi.util.rb.model.KeyValPair], trying to load the json data to the store. Once the data is loaded i am trying to access the loaded data through different store functions . But not getting it..? Can anyone find what I am missing..?
Store class
Ext.define('webUi.util.rb.ResourceBundle', {
extend: 'Ext.data.Store',
requires: [
'webUi.util.rb.model.KeyValPair'
],
constructor: function(config){
config = config || {};
var me = this;
Ext.applyIf(config, {
autoLoad: true,
model: 'webUi.util.rb.model.KeyValPair',
proxy:{
type: 'ajax',
url: webUi.util.AppSingleton.uiRsrcUrl,
noCache: true,
reader: {
type: 'json',
rootProperty: 'bundle'
},
getParams: Ext.emptyFn
},
listeners:{
'load': this.onBundleLoad,
scope: this
}
});
me.callParent([config]);
me.getProxy().on('exception', this.onBundleLoadException, this, {single: true});
},
onBundleLoad: function(store, record, success, op) {
if(success){
this.fireEvent('loaded');
} else{
this.fireEvent('loadError');
}
},
onBundleLoadException: function(){
console.dir(arguments);
},
onReady: function(fn){
this.readyFn = fn;
this.on('loaded', this.readyFn, this);
},
getMsg: function(key){
return this.getById(key)? Ext.util.Format.htmlDecode(this.getById(key).get('val')) : key + '.undefined';
}
});
Model Class
Ext.define('webUi.util.rb.model.KeyValPair', {
extend: 'Ext.data.Model',
config: {
idProperty: 'key',
fields: ['key', 'val']
}
});
JSON Response
{"bundle":[{"key":"one","val":"Oneee"},{"key":"two","val":"Twooo"}]}
my Code
var bundle = Ext.create('webUi.util.rb.ResourceBundle');
bundle.onReady(function(){
console.log('%%%%%%%%%%%%%');
console.log(bundle.getMsg('one'));
console.log(bundle.getById('one'));
console.log(bundle.getAt(0));
});
console.log
%%%%%%%%%%%%%
one.undefined
null
constructor {raw: Object, modified: Object, data: Object, hasListeners: HasListeners, events: Object…}
try using bundle.data.getMsg()