I have a grid linked to a store with autoLoad: true. The problem is that the store gets loaded on application launch, even if the view is created only later when accessed through a menu.
I have referenced the store in Application.js and in the view, but I'm not instatiating explicitly neither the store nor the view.
I don't know how to achieve that the store is loaded only when needed by the view.
If I set autoLoad: true, the store gets loaded on application launch.
If I set autoLoad: false, the store doesn't get loaded at all.
I know this is pretty basic, but I'm stuck so far.
Here is all the relevant code for reference:
app/store/Owners.js
Ext.define('Mb.store.Owners', {
extend: 'Ext.data.Store',
model: 'Mb.model.Owner',
autoLoad: true,
proxy: {
...
});
Application.js
Ext.define('Mb.Application', {
name: 'Mb',
extend: 'Ext.app.Application',
models: [
'Owner'
],
stores: [
'Owners'
],
...
app/view/Owners.js
Ext.define('Mb.view.winbiz.Owners', {
extend: 'Ext.grid.Panel',
alias: 'widget.test-gridPanel',
store: 'winbiz.Owners',
columns: [{
...
The view is instantiated in the controller:
Ext.define('Mb.controller.Winbiz', {
extend: 'Ext.app.Controller',
views: [
'Owners'
],
init: function(){
this.control({
'menu #test': {click: this.onMenuTest},
})
},
onMenuTest: function(){
this.getController('Main').addToMainTab('test-gridPanel');
},
You can add render handler to view which will call store load method and disable autoLoad.
Example listener:
Ext.define('Mb.view.winbiz.Owners', {
extend: 'Ext.grid.Panel',
[...],
initComponent: function(){
this.callParent();
this.on('render', this.loadStore, this);
},
loadStore: function() {
this.getStore().load();
}
});
I would let the view's controller handle the store load.
Start by disabling autoload on the store.
Ext.define('Mb.controller.Winbiz', {
extend: 'Ext.app.Controller',
views: [
'Owners'
],
ownerStore: null,
init: function(){
this.control({
'menu #test': {click: this.onMenuTest},
});
this.ownerStore = Ext.getStore('winbiz.Owners');
},
onMenuTest: function() {
if (this.ownerStore.loaded === false) {
this.ownerStore.load(
scope: this,
callback: this.onOwnerStoreLoaded
);
}
else {
this.addToTab();
}
},
onOwnerStoreLoaded: function (store, records, successful, eOpts) {
if (successful) {
store.loaded = true;
this.addToTab();
}
},
addToTab: function () {
this.getController('Main').addToMainTab('test-gridPanel');
}
Wheter you want to change the view before or after the store is loaded is another question.
This is my final controller code:
Ext.define('Mb.controller.Winbiz', {
extend: 'Ext.app.Controller',
views: [
'Owners'
],
refs: [{ref: 'testGrid', selector: 'test-gridPanel'}],
init: function(){
this.listen({
store: {
'#Owners':{ load: this.onOwnersLoad}
}
})
this.control({
'menu #test': {click: this.onMenuTest},
'test-gridPanel': {render: this.onOwnersRender}
})
},
onMenuTest: function(){
this.getController('Main').addToMainTab('test-gridPanel');
},
onOwnersLoad: function(store){
store.loaded = true
},
onOwnersRender: function(){
var store = this.getTestGrid().getStore();
if(!store.loaded)store.load();
},
It puts all code into the controller as suggested by #pcguru and uses the render event to shorten the code as suggested by #Lolo. Thanks
Related
The problem is in redirectTo calling onLoad method twice. From my main viewport extra views are loading dynamically.
Having main viewport
Ext.define('MyApp.main.view.MainView', {
extend: 'Ext.container.Container',
id: 'mainViewPort',
requires: [
'MyApp.main.controller.MainViewController',
],
xtype: 'app-main',
controller: 'main',
viewModel: {
type: 'main'
},
layout: {
type: 'border'
},
items: [{
region: 'center'
}]
});
viewport controller
Ext.define('MyApp.main.controller.MainViewController', {
extend: 'Ext.app.ViewController',
alias: 'controller.main',
onClickQueryResponses: function() {
var panelToAddName = Ext.create('MyApp.requests.view.QueryResponsesGridView', {});
var mainViewPort = Ext.getCmp('mainViewPort');
var centerRegion = mainViewPort.down('[region=center]');
centerRegion.removeAll();
centerRegion.add(panelToAddName);
}
});
view 'MyApp.requests.view.QueryResponsesGridView'
Ext.define('MyApp.requests.view.QueryResponsesGridView', {
extend: 'Ext.grid.Panel',
requires: [
'MyApp.requests.controller.QueryResponsesGridViewController'
],
controller: 'queryResponsesGrid',
dockedItems: [{
xtype: 'toolbar',
items:[{
xtype: 'button',
margin: '0 30 0 4',
handler: 'onClickQuerySearch'
}]
}]
});
});
controller of view 'MyApp.requests.view.QueryResponsesGridView'
Ext.define('MyApp.requests.controller.QueryResponsesGridViewController', {
extend: 'Ext.app.ViewController',
alias: 'controller.queryResponsesGrid',
routes : {
'responses': {
action : 'onLoad'
}
},
onLoad: function() {
this.redirectTo('responses');
alert('!');
},
onClickQuerySearch: function() {
this.onLoad();
},
});
When I click button with handler onClickQuerySearch alert('!') is running twice, do anyone know why?
here is the fiddle https://fiddle.sencha.com/#fiddle/oqb
I don't think you need to call redirectTo in the onLoad method. You are basically creating a self-referencing loop. redirectTo is then calling onLoad again.
I think possibly you want the redirectTo in the onClickQuerySearch instead of calling onLoad directly:
Ext.define('MyApp.controller.QueryResponsesGridViewController', {
extend: 'Ext.app.ViewController',
alias: 'controller.queryResponsesGrid',
routes : {
'responses': {
action : 'onLoad'
}
},
onLoad: function() {
alert('!');
},
onClickQuerySearch: function() {
this.redirectTo('responses');
}
});
I have a basic users.json file, a user model and a users store. The size of the store is 0 when I call getCount().
My initial idea was to add a listener for the load event. However, even just calling getStore() returns empty data.
Can you see were I have gone wrong?
{
"users":[
{
"name": "Mike Henderson",
},
{
"name": "Sally Michael",
},
{
"name": "Rory Muldoon",
}
]
}
Ext.define('TP.model.User', {
extend: 'Ext.data.Model',
config: {
fields: ['name']
}
});
Ext.define('TP.store.Users', {
extend: 'Ext.data.Store',
config:{
autoload: true,
model: 'TP.model.User',
storeId: 'Users',
proxy : {
type: 'ajax',
url: 'data/users.json',
reader: {
rootProperty: 'users',
type: 'json'
}
}
}
});
Ext.application({
name: 'TP',
views: ['Main'],
models:['User'],
stores:['Users'],
launch: function() {
// Destroy the #appLoadingIndicator element
Ext.fly('appLoadingIndicator').destroy();
// Initialize the main view
Ext.Viewport.add(Ext.create('TP.view.Main'));
Ext.getStore('Users').on('load', this.onStoreLoad, this);
console.log(Ext.getStore('Users').getCount());
},
onStoreLoad: function(self, records, success, operation) {
console.log("loaded store");
}
});
I found the solution in the end, it was simple typo.
In the store config - autoload needs to be autoLoad (Capital L)
How can I call a new view on image tap which is defined in tpl.
Code:
tpl: Ext.create('Ext.XTemplate','<tpl for="sample">',
'<div> {tittle}</div>
<div><img src="{photo}"/></div>',
'</tpl>',
/////////////////////////////////////////
After your directions, I'm sure I have something wrong. I just want to know how to link an image to puncture it take you to another view. Let me explain better?
Thank you very much for your time and dedication.
//MyController
Ext.define('DemoApp.controller.ControllerR', {
extend: 'Ext.app.Controller',
config: {
refs: {
res: 'res',
},
control: {
'rest list': {
itemtap: 'showR' },
}
},
onCreateNewView: function() {
if(document.getElementById('something')) {
Ext.Viewport.setActiveItem(Ext.create('DemoApp.view.DetalTwo'));
}
},
});
//My Template
Ext.define('DemoApp.view.ViewR', {
extend: 'Ext.Panel',
xtype: 'res',
config: {
title: 'Res',
iconCls: 'info',
scrollable: true,
data: {
res: [ model: 'DemoApp.model.ModelR',
autoLoad: true,
storeId: 'resStore',
proxy: {
type: 'ajax',
url: 'data/res.json',
reader: {
type: 'json',
rootProperty:'wha.res'
}
}]
},
tpl: Ext.create('Ext.XTemplate','<tpl for="sample">',
'<div> {tittle}</div>
<div><img id="something "src="{photo}"/></div>',
'</tpl>',
{
join: function(value) {
return value.join(', ');
}
})
}
});
You can give an id to image tag i.e. <img id = "something"/> and if tpl is defined for list then go to that list's handling function in controller or in view(where you defined a list and listeners) and write this code:
if(document.getElementById('Your img tag id')) {
// create a view and active it
}
For Example:
onCreateNewView: function() {
if(document.getElementById('something')) {
Ext.Viewport.setActiveItem(Ext.create('DemoApp.view.NewView'));
}
}
First thing first... you should do some google before putting such question in Stack.Your Code is totally wrong as well as it contains major syntax errors. And we are not here to solve some stupid syntax errors.Anyways Let me explain something..
1.) In your controller you are trying to bind 'itemtap' event.You can only bind 'itemtap' event if there is a list in your view. Here, in your case there is no list.
2.) And in controller it's look like something this:
refs: {
imageList: '#imageList',
},
control: {
'imageList': {
itemtap: 'onCreateNewView'
},
}
3.) Create a list in your view:
config: {
items: [
{
xtype: 'list',
id: 'imageList',
itemId: 'imageList',
tpl:'Your tpl code'
}
]
}
I am trying to fetch some post form my WordPress blog in my Sencha application.
But I keep on getting this error "consle is not defined".
Hare is my code for different files.
App.js
Ext.Loader.setPath({
'Ext': 'touch/src',
'ov_app': 'app'
});
Ext.application({
name: 'ov_app',
requires: [
'Ext.MessageBox'
],
profiles: ['Phone', 'Tablet', 'Desktop'],
views: ['Main', 'Eligibelity', 'HeaderBar', 'ListNavigation', 'FooterBar', 'home_button', 'main_navigation', 'Corporateclints', 'Question_form', 'Quick_Enquiry', 'sinlgepost'],
stores: ['NavigationItems', 'GetContent'],
models: ['Items', 'PostContent', 'MainNavigation' ],
controllers: ['MainController'],
launch: function() {
// Destroy the #appLoadingIndicator element
Ext.fly('appLoadingIndicator').destroy();
// Initialize the main view
ov_app.container = Ext.Viewport.add(Ext.create('ov_app.view.Main'));
},
});
GetContent.js
Ext.define('ov_app.model.PostContent', {
extend:'Ext.data.Model',
config:{
fields: [
{name: 'content'}
]
}
});
GetContent.js
Ext.define('ov_app.store.GetContent', {
extend: 'Ext.data.Store',
config:{
model: 'ov_app.model.PostContent',
autoLoad :true,
proxy:{
type:'jsonp',
url:'http://www.one-visa.com/api/get_post/?id=2798',
reader:{
type:'json',
rootProperty:'post'
},
}
}
});
sinlgepost.js
Ext.define('ov_app.view.sinlgepost', {
xtype:'sinlgepost',
extend:'Ext.Container',
config:{
xtype: 'data',
store: 'getcontent',
itemTpl: '<p>{content}</p>'
}
});
I really not getting any idea what I am doing wrong.
The error "consle is not defined" has clearly pointed out the mistake you've made: if you want to access the console object, its name is console not consle.
I want to display a popout window with some values displayed on it fetched from a PHP server file. I have no clue how to display the items on the window.
I don't know why but the console.log message 'method call' in the controller doesn't get displayed when the view is rendered. I think this is because i have added click: this.methodcall (which gets called only when a button click is made, but i want the log statement to print when the view is rendered)
Nothing gets displayed on the View, i think this is because i have not added any code to display it in the View.
Can someone help me solve this problem ?
My Pop out window VIEW code;
Ext.define('Project.view.user.Popupwin', {
extend: 'Ext.window.Window',
alias: 'widget.popupwin',
layout:'fit',
autoShow: true,
initComponent: function() {
this.store = 'Popupwin';
this.items = [
{
xtype: 'form',
items: [
]
}
];
this.callParent(arguments);
}
});
STORE
Ext.define('Project.store.Popupwin',{
extend:'Ext.data.Store',
model:'App.model.Popupwin',
proxy: {
actionMethods : {
read : 'POST'
},
type: 'ajax',
url : 'loaddata.php',
autoLoad: true
}
});
CONTROLLER
Ext.define('Project.controller.Popupwin',{
extend: 'Ext.app.Controller',
stores:['Popupwin'],
models:['Popupwin'],
views:['DoctorView'],
init: function(){
console.log('executed');
this.control({
'popupwin': {
click: this.methodcall
}
});
},
methodcall: function() {
console.log('method call');
this.getShowPopupwinStore().load();
}
});
Model
Ext.define ('Project.model.Popupwin',{
extend: 'Ext.data.Model',
fields:['fname','lanme']
});
Window has no click event, so you can't listen for it.
Ext.define('MyWindow', {
extend: 'Ext.window.Window',
afterRender: function(){
this.callParent(arguments);
this.el.on('click', this.fireClick, this);
},
fireClick: function(e, t){
this.fireEvent('click', this, e);
}
});