ExtJS 6 - Store $binding is undefined - javascript

I need to perform certain operations when a store is loaded. The problem is when the 'load' event of the store is triggered, '$binding' is undefined, and thus the 'owner' property is unavailable.
The store and its listener for the 'load' event are defined in the ViewModel:
Ext.define('App.view.TSegmentacionFrmViewModel', {
extend: 'Ext.app.ViewModel',
alias: 'viewmodel.TSegmentacionFrm',
requires: [
'Ext.data.Store',
'Ext.data.proxy.Ajax',
'Ext.data.reader.Json'
],
stores: {
oStoreSegmentacion: {
autoLoad: true,
model: 'App.model.oGrid',
proxy: {
type: 'ajax',
extraParams: {
cmd: 'Get',
cCodClass: 'SegmentacionBrw'
},
url: "TGlobalData.ashx",
useDefaultXhrHeader: false,
reader: {
type: 'json',
rootProperty: 'aResultado',
totalProperty: 'nRows'
}
},
listeners: {
load: 'onJsonstoreLoad'
}
}
}
});
The store binding is defined in the View (line 58 of the following code):
Ext.define('App.view.TSegmentacionFrm', {
extend: 'Ext.tab.Panel',
alias: 'widget.TSegmentacionFrm',
requires: [
'App.view.TSegmentacionFrmViewModel',
'App.view.TSegmentacionFrmViewController',
'Ext.tab.Tab',
'Ext.toolbar.Toolbar',
'Ext.toolbar.Separator',
'Ext.grid.Panel',
'Ext.view.Table',
'Ext.grid.column.Action',
'Ext.form.Label',
'Ext.grid.column.RowNumberer'
],
config: {
[...]
},
controller: 'TSegmentacionFrm',
viewModel: {
type: 'TSegmentacionFrm'
},
cls: 'CustomTabs',
itemId: 'TSegmentacionFrm',
activeTab: 0,
deferredRender: false,
initConfig: function(instanceConfig) {
var me = this,
config = {
items: [
{
xtype: 'panel',
itemId: 'oPnlHist',
layout: {
type: 'vbox',
align: 'stretch'
},
bind: {
title: '{lbl_ListadoHist}'
},
dockedItems: [
{
[...]
}
],
items: [
{
xtype: 'TMainBrowseGrid',
cBrwName: 'oBrwSegmentacion',
cCodForm: 'SegmentacionFrm',
cls: 'CustomGrid',
flex: 1,
itemId: 'oGridHistorico',
bind: {
store: '{oStoreSegmentacion}'
},
listeners: {
selectionchange: 'onOGridProductosSelectionChange'
},
columns:
[...]
}
]
},
]
};
[...]
},
});
And this is the onJsonstoreLoad method, in the ViewController:
Ext.define('App.view.TSegmentacionFrmViewController', {
extend: 'Ext.app.ViewController',
alias: 'controller.TSegmentacionFrm',
onJsonstoreLoad: function (store, records, successful, operation, eOpts) {
// This '$binding' is undefined
// Uncaught TypeError: Cannot read property 'owner' of undefined at g.onJsonstoreLoad
var oView = store.$binding.owner.getView();
[...]
}
});
What am I doing wrong? The person who wrote this some time ago says it worked, but now it seems to be broken. Thank you.

$binding is some internal property, it's not part of the API, don't use it. By virtue of the callback being in the controller, just call this.getView().

Related

ExtJS: Is possible to state if else condition for bind in grid panel?

Inside the ViewModel I've defined 2 stores and I'm using a gridpanel as view. Is there any chance to state if else condition for bind property inside gridpanel?
ViewModel:
stores: {
dataStore: {
model: 'MyApp.first.Model',
autoLoad: true,
session: true
},
listStore: {
model: 'MyApp.second.Model',
autoLoad: true,
session: true,
},
and on grid panel I want to do this condition;
Ext.define('MyApp.base.Grid', {
extend: 'Ext.grid.Panel',
// Currently binds directly to listStore
bind: '{listStore}',
// but I'm trying to implement a proper adjustment such as this;
// bind: function () {
// var username = localStorage.getItem('username');
// if (username === 'sample#adress.com') {'{dataStore}';} else {'{listStore}'}
// },
You can't use conditional expressions with bind, however, you can use ViewModel's formulas to select which store to use with grid. Here is example of such formula:
conditionalStore: function (get) {
var param = get('param');
if (param === 1) {
return get('simpsonsStore');
}
return get('griffinsStore');
}
And here is working fiddle, which you can play with: https://fiddle.sencha.com/#view/editor&fiddle/2eq2
You can use bindStore method of grid.
In this FIDDLE, I have created a demo using grid. I hope this will help/guide you to achieve your requirement.
CODE SNIPPET
Ext.application({
name: 'Fiddle',
launch: function () {
//defining store 1
Ext.define('Store1', {
extend: 'Ext.data.Store',
alias: 'store.store1',
autoLoad: true,
fields: ['name', 'email', 'phone'],
proxy: {
type: 'ajax',
url: 'data1.json',
reader: {
type: 'json',
rootProperty: ''
}
}
});
//defining store 2
Ext.define('Store2', {
extend: 'Ext.data.Store',
alias: 'store.store2',
autoLoad: true,
fields: ['name', 'email', 'phone'],
proxy: {
type: 'ajax',
url: 'data2.json',
reader: {
type: 'json',
rootProperty: ''
}
}
});
//defining view model
Ext.define('MyViewModel', {
extend: 'Ext.app.ViewModel',
alias: 'viewmodel.myvm',
stores: {
gridStore1: {
type: 'store1'
},
gridStore2: {
type: 'store2'
}
}
});
//creating grid
Ext.create({
xtype: 'grid',
title: 'Example of bind the store',
renderTo: Ext.getBody(),
viewModel: {
type: 'myvm'
},
columns: [{
text: 'Name',
dataIndex: 'name'
}, {
text: 'Email',
dataIndex: 'email',
flex: 1
}, {
text: 'Phone',
dataIndex: 'phone'
}],
tbar: [{
text: 'Load Store1',
handler: function (btn) {
var grid = this.up('grid');
grid.bindStore(grid.getViewModel().getStore('gridStore1'))
}
}, {
text: 'Load Store2',
handler: function (btn) {
var grid = this.up('grid');
grid.bindStore(grid.getViewModel().getStore('gridStore2'))
}
}]
});
}
});

ExtJs: How to show viewmodel after store load

I need that my viewmodel MainModel appears after store 'OrgStore' load.
Now I have next App.js:
Ext.application({
name: 'BillWebApp',
extend: 'BillWebApp.Application',
stores: ['OrgStore'],
requires: [
'BillWebApp.view.main.Main'
],
launch: function () {
var store = Ext.getStore('OrgStore');
store.on('load', function() {
BillWebApp.getApplication().setMainView('main.Main');
});
},
...
OrgStore:
Ext.define('BillWebApp.store.OrgStore', {
extend: 'Ext.data.Store',
alias : 'store.orgstore',
storeId: 'OrgStore',
model: 'BillWebApp.model.Org',
config:{
autoLoad: true,
autoSync: true
},
proxy: {
autoSave: false,
type: 'ajax',
api: {
create : '',
read : '/base/getOrgAll',
update : '',
destroy : ''
},
reader: {
type: 'json'
}
}, listeners: {
load: function() {
console.log("OrgStore loaded!");
}
}
});
MainModel:
Ext.define('BillWebApp.view.main.MainModel', {
extend: 'Ext.app.ViewModel',
alias: 'viewmodel.main',
data: {
name: 'BillWebApp',
},
stores: {
orgstore: {
type: 'orgstore'
}
}
});
Why I in log window see message "OrgStore loaded!" twice?
One after 'OrgStore' loaded, and next one after MainModel started?
I think I invoke two instances of 'OrgStore'....
How can I change my code to show MainModel after store fully load?

Use same view several times simultaneously in Sencha Touch

My problem is the following:
I have a view (for example: view A), which it will be used by another view ( twice, but showing different data.
ViewA:
Ext.define('view_A', {
extend: 'Ext.DataView',
xtype: 'view_A',
config: {
store: 'Children',
baseCls: 'facesGrid',
itemTpl: [
'<div class="image" style="background-image:url({Picture})"></div>',
'<div class="name">{PrivateName} {shortFamilyName}.</div>'
]
}
});
ViewB
Ext.define('view_B', {
extend: 'Ext.Container',
config: {
layout: 'vbox',
cls: 'messageDetails',
items: [
{
xtype: 'view_A',
itemId: 'students',
flex: 1
},
{
xtype: 'view_A',
itemId: 'teachers',
flex: 1
}
]
}
});
Controller
Ext.define('myController', {
extend: 'Ext.app.Controller',
config: {
refs: {
view_B: 'view_B'
},
control: {
view_B: {
activate: 'onActivateCard'
}
}
},
onActivateCard: function () {
var viewB = this.getView_B();
Ext.getStore('storeA').load({
callback: function (records, operation, success) {
viewB.getComponent('students').setData(records);
},
scope: this
});
Ext.getStore('storeB').load({
callback: function (records, operation, success) {
viewB.getComponent('teachers').setData(records);
},
scope: this
});
}
});
The problem is that it's showing the same data twice.
The solution I found create another view (for example view_AA) inheriting from view_A, but I'm not sure it's the best practice.
What is the solution? What am I doing wrong?
Thanks
Sebastian
The solution is very easy, the store should not be defined in viewA, son it must be defined in view B.
Ext.define('view_A', {
extend: 'Ext.DataView',
xtype: 'view_A',
config: {
//store: 'Children', <--- REMOVE FROM HERE!!!
baseCls: 'facesGrid',
itemTpl: [
'<div class="image" style="background-image:url({Picture})"></div>',
'<div class="name">{PrivateName} {shortFamilyName}.</div>'
]
}
});
Ext.define('view_B', {
extend: 'Ext.Container',
config: {
layout: 'vbox',
cls: 'messageDetails',
items: [
{
xtype: 'view_A',
itemId: 'students',
store: 'storeA', //<--- THE STORE IS DEFINED HERE
flex: 1
},
{
xtype: 'view_A',
itemId: 'teachers',
store: 'storeB', //<--- THE STORE IS DEFINED HERE
flex: 1
}
]
}
});
Hope this help to everyone!
Sebastian

selectfield not loading on build

I am almost giving up. I’ve being trying for almost a month to develop an app using sencha touch 2.2.1 and sencha cmd 3.1.2.324. All works on development, but after create the production file (sencha app build) my selectfield do not load.
Actually I’d isolated all pages on the app and I am working just with few cards. From chrome I can check the webservice is called and return as expected. The console doesn’t show any error, but the selectfield remain empty.
Any clue?
Panel:
Ext.define('MySecondApp.view.Home', {
extend: 'Ext.Panel',
xtype: 'mg_home',
config:
{
title: 'Home',
id: 'tabHome',
iconCls: 'info',
layout: 'vbox',
xtype: 'panel',
items:
[
{docked: 'top',xtype: 'titlebar',title: 'Home'},
{
xtype: 'selectfield',
name: 'selectMesHome',
id: 'selectMesHome',
action: 'selectMesHome',
label: 'Mes', /*TODO*/
scrollable: true,
displayField: 'dc_data',
valueField: 'vl_data',
store: 'mesesHome'
},
{
xtype: 'panel',
id: 'home_content',
html: 'carregando...'
}
]
}
});
model:
Ext.define('MySecondApp.model.Meses', {
extend: 'Ext.data.Model',
config: {
fields :
[
{name:'dc_data', type:'string'},
{name:'vl_data', type:'string'}
]
}
});
store:
Ext.define('MySecondApp.store.mesesHome', {
extend: 'Ext.data.Store',
storeId: 'mesesHomeStore',
config: {
model: 'MySecondApp.model.Meses',
autoLoad: true,
proxy:
{
type: 'ajax',
url: 'http://www.meusgastos.com.br/touch/rest/meses.php',
reader:
{
type: 'json',
root: 'data'
}
}
}
});
ajax request some credentials previous saved (and tested, and working). The response will be:
{
"HEADER": [],
"vl_atual": "201308",
"data": [
{
"dc_data": "Agosto/2013",
"vl_data": "201308"
},
{
"dc_data": "Julho/2013",
"vl_data": "201307"
},
{
"dc_data": "Junho/2013",
"vl_data": "201306"
},
{
"dc_data": "Maio/2013",
"vl_data": "201305"
},
{
"dc_data": "Abril/2013",
"vl_data": "201304"
},
{
"dc_data": "Março/2013",
"vl_data": "201303"
}
]
}
Make these changes and try again
In Store (MySecondApp.store.mesesHome)
1) Put the storeId inside config
2) change reader root as rootProperty
So, store looks like this
Ext.define('MySecondApp.store.mesesHome', {
extend: 'Ext.data.Store',
config: {
storeId: 'mesesHomeStore',
model: 'MySecondApp.model.Meses',
autoLoad: true,
proxy:
{
type: 'ajax',
url: 'http://www.meusgastos.com.br/touch/rest/meses.php',
reader:
{
type: 'json',
rootProperty: 'data'
}
}
}
});
In view (MySecondApp.view.Home)
This change is not necessary, But still i suggest you to do this.
Give storeId to store property of selectfield
{
xtype: 'selectfield',
name: 'selectMesHome',
id: 'selectMesHome',
action: 'selectMesHome',
label: 'Mes', /*TODO*/
scrollable: true,
displayField: 'dc_data',
valueField: 'vl_data',
store: 'mesesHomeStore'
},

Sencha Touch. Ext.getStore() function

I'm trying to learn sencha touch by Oreilly application example which is produced in sencha touch documentation examples. Ext.getStore function returns undefined.
Code:
Ext.application({
//name space of application
name: 'sample',
title: '<img src="lib/resources/images/home.png"/>',
webserviceUrl: 'http://xxx/yyy/zzz.svc/',
requires: ['sample.util.Proxy'],
view: [
'Viewport',
'wares.lists.Popular',
'wares.lists.List'
],
model: [
'WaresListItem'
],
store: [
'Wares'
],
launch: function() {
Ext.Viewport.setMasked({ xtype: 'loadmask' });
sample.util.Proxy.process(function () {
Ext.create('sample.views.Viewport');
Ext.Viewport.setMasked(false);
});
}
});
//------
Ext.define('sample.views.Viewport', {
extend: 'Ext.tab.Panel',
title: 'Hello world!',
xtype: 'viewport',
config: {
fullscreen: true,
tabBar: {
docked: 'bottom',
},
items: [
{ xclass: 'sample.views.wares.lists.Popular' },
]
}
});
//-----
Ext.define('sample.views.wares.lists.Popular', {
extend: 'Ext.NavigationView',
requires: ['sample.views.wares.lists.List'],
xtype: 'Popular',
config: {
iconCls: 'home',
title: 'List',
items: [
{
xtype: 'wares',
}
]
}
});
//-----
Ext.define('sample.views.wares.lists.List', {
extend: 'Ext.List',
xtype: 'wares',
config: {
store: 'Wares',
itemTpl: {}
},
initialize: function () {
this.config.title = sample.app.title;
}
});
//-----
Ext.define('sample.util.Proxy', {
singleton: true,
requires: ['Ext.Ajax'],
process: function(callback) {
var wareListStore = Ext.getStore('Wares'); //returns undefinded
var wareModel;
console.log("Store: ", wareListStore);
Ext.Ajax.request({
url: sample.app.webserviceUrl + 'getSomeItems',
disableCaching: false,
useDefaultXhrHeader: false,
headers: {
"Content-Type": "application/json"
},
method: 'POST',
params: JSON.stringify({"Type":3}),
success: function (response) {
var result = JSON.parse(response.responseText);
if(true === result.Header.Status) {
Ext.Array.each(result.Body, function (ware) {
wareModel = Ext.create('sample.models.WaresListItem', ware);
// wareListStore.add(wareModel); //raises an error
});
} else {
console.log("Error code: %i", result.Header.ErrorCode);
}
},
failure: function (response) {
console.log('Houston, we have a problem!');
console.log(JSON.stringify(response));
}
});
callback();
}
});
//-----
Ext.define('sample.store.Wares', {
extend: 'Ext.data.Store',
config: {
model: "sample.models.WaresListItem"
}
});
I rewrote everything like in an example. What I have missed?
UPDATED: In console I see that store objects script isn't included at all.
Array names must be given these names views, controllers, models, stores and so on. Renaming the arrays fixed it.
Ext.define('sample.store.Wares', {
extend: 'Ext.data.Store',
config: {
model: "sample.models.WaresListItem",
storeId: 'Wares'
}
});
Try this should work... Hope it helps...

Categories

Resources