My store is taking time to load.so that i want to display a loading indicator while loading store data.Is there any function to know the list store is completely loaded or not?
Please help me..I was searching for this long time..
Here is my code:
Ext.Viewport.setMasked({
xtype: 'loadmask',
message: 'Loading'
});
Ext.define('MyApp.view.Myview1',
{
extend: 'Ext.Panel',
requires: ['Ext.List', 'Ext.util.JSON'],
config: {
layout: 'hbox',
items: [
{
xtype: 'panel',
layout: 'fit',
flex: 1,
items: [
{
xtype: 'list',
itemTpl:
'<div class="myContent">' +
'<div>{name}</div>' +
'</div>',
store: 'MainStore',
disclosure: true,
store.on({
load: {
fn: function( store ) {
Ext.Viewport.setMasked(false);
},
scope: this,
single: true
}
});
store.load();
}
]
}
]
}
});
My requirement is to display indicator while loading data from store and remove it after the list have all data from store.
You will have to bind load event to this store like below code
Ext.Viewport.setMasked({
xtype: 'loadmask',
message: 'Loading'
});
store.on({
load: {
fn: function( store ) {
Ext.Viewport.setMasked(false);
},
scope: this,
single: true
}
});
store.load();
This one is simple, just like #Naresh Said
put load mask inside your function
Ext.Viewport.setMasked({
xtype: 'loadmask',
message: 'Please Wait...'
});
and disable loadmask after store loads
storectn.load({
callback: function (records, operation, success, response) {
if (success==1) {
// Ext.Msg.alert('success');
Ext.Viewport.setMasked(false);
} else {
// Ext.Msg.alert('Failed');
Ext.Viewport.setMasked(false);
}
}
});
Finally I have solved the problem :)
Sencha loads the store and list within a very short time but the UI takes long time to load. So, after finish loading the stores if you set a callback to remove indicator using setTimeout then the problem will be solved. Because when UI loading is finished it will call your final method, because JavaScript is a single thread language.
Ext.Viewport.setMasked({
xtype: 'loadmask',
message: 'Loading'
});
store.on({
load: {
fn: function( store ) {
setTimeout(function(){
Ext.Viewport.setMasked(false);
}, 100);
},
scope: this,
single: true
}
});
store.load();
Here even though the setTimeout is supposed to be called after 100 milliseconds, it will wait for the UI to be loaded first and then be called.
If you are loading the store dynamically by a custom query with store.add(Record), then after loading all data you just call the setTimeout call. It will work as well.
We need to setmask(prevent user interaction and show loading message) while loading data in sencha touch. Sencha touch setMasked(<>) gives option to add mask into containers. But every time we need to manually add the mask and remove the mask. Instant of this manually doing things we can use store listeners.
My requirement here is i have a one store for CRUD process. So every time when i try to sync and loading the data’s i want to setmask of the view. My store code is like the below.
I used beforeload, beforesync, load, metachange, removerecords, updaterecord, write, addrecords events for this task.
Please visit the below url for full source code by clicking the link. [Solved by solution]
http://saravanakumar.org/blog/2014/04/sencha-touch-setmask-display-load-mask-or-waiting-while-loading-data-in-store/
Related
I'm new to rally app SDK and trying to do the tutorials (from Youtube and from rally site)
when I'm trying to create an iterationComboBox the object is created but with no values ("There are no Iterations defined").
i tried to run both the video tutorial code from github (session_4_interactive_grid)
// Custom Rally App that displays Defects in a grid and filter by Iteration and/or Severity.
//
// Note: various console debugging messages intentionally kept in the code for learning purposes
Ext.define('CustomApp', {
extend: 'Rally.app.App', // The parent class manages the app 'lifecycle' and calls launch() when ready
componentCls: 'app', // CSS styles found in app.css
defectStore: undefined, // app level references to the store and grid for easy access in various methods
defectGrid: undefined,
// Entry Point to App
launch: function() {
console.log('our second app'); // see console api: https://developers.google.com/chrome-developer-tools/docs/console-api
this.pulldownContainer = Ext.create('Ext.container.Container', { // this container lets us control the layout of the pulldowns; they'll be added below
id: 'pulldown-container-id',
layout: {
type: 'hbox', // 'horizontal' layout
align: 'stretch'
}
});
this.add(this.pulldownContainer); // must add the pulldown container to the app to be part of the rendering lifecycle, even though it's empty at the moment
this._loadIterations();
},
// create iteration pulldown and load iterations
_loadIterations: function() {
this.iterComboBox = Ext.create('Rally.ui.combobox.IterationComboBox', {
fieldLabel: 'Iteration',
labelAlign: 'right',
width: 300,
listeners: {
ready: function(combobox) { // on ready: during initialization of the app, once Iterations are loaded, lets go get Defect Severities
this._loadSeverities();
},
select: function(combobox, records) { // on select: after the app has fully loaded, when the user 'select's an iteration, lets just relaod the data
this._loadData();
},
scope: this
}
});
this.pulldownContainer.add(this.iterComboBox); // add the iteration list to the pulldown container so it lays out horiz, not the app!
},
// create defect severity pulldown then load data
_loadSeverities: function() {
this.severityComboBox = Ext.create('Rally.ui.combobox.FieldValueComboBox', {
model: 'Defect',
field: 'Severity',
fieldLabel: 'Severity',
labelAlign: 'right',
listeners: {
ready: function(combobox) { // this is the last 'data' pulldown we're loading so both events go to just load the actual defect data
this._loadData();
},
select: function(combobox, records) {
this._loadData();
},
scope: this // <--- don't for get to pass the 'app' level scope into the combo box so the async event functions can call app-level func's!
}
});
this.pulldownContainer.add(this.severityComboBox); // add the severity list to the pulldown container so it lays out horiz, not the app!
},
// Get data from Rally
_loadData: function() {
var selectedIterRef = this.iterComboBox.getRecord().get('_ref'); // the _ref is unique, unlike the iteration name that can change; lets query on it instead!
var selectedSeverityValue = this.severityComboBox.getRecord().get('value'); // remember to console log the record to see the raw data and relize what you can pluck out
console.log('selected iter', selectedIterRef);
console.log('selected severity', selectedSeverityValue);
var myFilters = [ // in this format, these are AND'ed together; use Rally.data.wsapi.Filter to create programatic AND/OR constructs
{
property: 'Iteration',
operation: '=',
value: selectedIterRef
},
{
property: 'Severity',
operation: '=',
value: selectedSeverityValue
}
];
// if store exists, just load new data
if (this.defectStore) {
console.log('store exists');
this.defectStore.setFilter(myFilters);
this.defectStore.load();
// create store
} else {
console.log('creating store');
this.defectStore = Ext.create('Rally.data.wsapi.Store', { // create defectStore on the App (via this) so the code above can test for it's existence!
model: 'Defect',
autoLoad: true, // <----- Don't forget to set this to true! heh
filters: myFilters,
listeners: {
load: function(myStore, myData, success) {
console.log('got data!', myStore, myData);
if (!this.defectGrid) { // only create a grid if it does NOT already exist
this._createGrid(myStore); // if we did NOT pass scope:this below, this line would be incorrectly trying to call _createGrid() on the store which does not exist.
}
},
scope: this // This tells the wsapi data store to forward pass along the app-level context into ALL listener functions
},
fetch: ['FormattedID', 'Name', 'Severity', 'Iteration'] // Look in the WSAPI docs online to see all fields available!
});
}
},
// Create and Show a Grid of given defect
_createGrid: function(myDefectStore) {
this.defectGrid = Ext.create('Rally.ui.grid.Grid', {
store: myDefectStore,
columnCfgs: [ // Columns to display; must be the same names specified in the fetch: above in the wsapi data store
'FormattedID', 'Name', 'Severity', 'Iteration'
]
});
this.add(this.defectGrid); // add the grid Component to the app-level Container (by doing this.add, it uses the app container)
}
});
and the code from Rally site (https://help.rallydev.com/apps/2.0rc2/doc/#!/guide/first_app).
// Custom Rally App that displays Defects in a grid and filter by Iteration and/or Severity.
//
// Note: various console debugging messages intentionally kept in the code for learning purposes
Ext.define('CustomApp', {
extend: 'Rally.app.App', // The parent class manages the app 'lifecycle' and calls launch() when ready
componentCls: 'app', // CSS styles found in app.css
launch: function() {
this.iterationCombobox = this.add({
xtype: 'rallyiterationcombobox',
listeners: {
change: this._onIterationComboboxChanged,
ready: this._onIterationComboboxLoad,
scope: this
}
});
},
_onIterationComboboxLoad: function() {
var addNewConfig = {
xtype: 'rallyaddnew',
recordTypes: ['User Story', 'Defect'],
ignoredRequiredFields: ['Name', 'ScheduleState', 'Project'],
showAddWithDetails: false,
listeners: {
beforecreate: this._onBeforeCreate,
scope: this
}
};
this.addNew = this.add(addNewConfig);
var cardBoardConfig = {
xtype: 'rallycardboard',
types: ['Defect', 'User Story'],
attribute: 'ScheduleState',
storeConfig: {
filters: [this.iterationCombobox.getQueryFromSelected()]
}
};
this.cardBoard = this.add(cardBoardConfig);
},
_onBeforeCreate: function(addNewComponent, record) {
record.set('Iteration', this.iterationCombobox.getValue());
},
_onIterationComboboxChanged: function() {
var config = {
storeConfig: {
filters: [this.iterationCombobox.getQueryFromSelected()]
}
};
this.cardBoard.refresh(config);
}
});
both give me an empty iteration box.
i'm getting user stories data when running code from session 3 on the video,by creating a store of user stories. I googled it and searched here for duplicates but with no successso far, so what can be the issue?
Thanks!
I copied the code you posted, both apps, without making any changes, ran the apps and the iteration box was populated in both cases. It's not the code.
Maybe if you are getting "There are no Iterations defined" there are no iterations in your project?
The second code you posted which you copied from the example in the documentation has a bug in it and even though the iteration combobox is populated, the cards do not show on a board. DevTools console has error: "Cannot read property 'refresh' of undefined".
I have a working version of this app in this github repo.
I can't figure out why my data won't load to my AccordionList element from here:
https://github.com/kawanoshinobu/Ext.ux.AccordionList
I'm creating it within a panel like so:
{
xtype: 'accordionlist',
store: Ext.create('Rks.store.Bcks'),
flex: 1
},
It calls a store which is defined like so:
Ext.define('Rks.store.Bcks', {
extend: 'Ext.data.TreeStore',
requires: ['Rks.model.Bck'],
config: {
itemId: 'bks',
model: 'Rks.model.Bck',
defaultRootProperty: 'items',
proxy: {
type: 'ajax',
url: 'path/to/ajax',
},
autoLoad: false,
listeners:{
load: function( me, records, successful, operation, eOpts ){
console.log("data loaded", records);
}
}
}
});
When I call the view which contains the accordion, the console logs what appears to be a good object:
items: [{bck_id:3, author_id:1, title:test, items:[{c_id:2, bck_id:3, title:choice1, leaf:true}]}]
But nothing shows up. The panel is empty and no accordion items show.
However, when I replace the proxy with inline JSON, everything looks fine:
Ext.define('Rks.store.Bcks', {
extend: 'Ext.data.TreeStore',
requires: ['Rks.model.Bck'],
config: {
itemId: 'bks',
model: 'Rks.model.Bck',
defaultRootProperty: 'items',
root: {
items: [
{ bck_id: 1, author_id: 1, title: 'bck1', items: [ {c_id: 1, bck_id: 1, title: 'choice1', leaf: true} ] }
]
}
autoLoad: false,
listeners:{
load: function( me, records, successful, operation, eOpts ){
console.log("data loaded", records);
}
}
}
});
Here the items show up in the accordion. I can't figure out why the second example works and the first doesn't. Is there something special I should be doing when calling the store proxy for Accordion?
UPDATE: I have managed to get the accordion list to display data, but when I change the url of the store and reload it, the store reloads but the accordion list does not update. The accordion list continues to display the data it receives from the first URL, not from reloads with modified URLS.
Thanks
I think I figured this out. For the accordionlist component, you need to do like so:
var accordionlist = Ext.ComponentQuery.query('rdb #rdb1')[0];
var brickstore = Ext.getStore('bcs');
bcs.removeAll();
bcs.getProxy().setUrl('newurl');
accordionlist.setStore(bcs);
accordionlist.load();
basically, manually remove all items, set the new url, set the store on the list, then load the list.
I think there was a problem with your proxy configuration. First, remove the defaultRootProperty config (which is out of proxy config), then try this:
proxy: {
type: 'ajax',
url: (your ajax url),
reader: {
type: 'json',
rootProperty: 'items'
}
},
I want to use value from controller to filter store.I put this code:
My Controller:
showCatQuery: function(list,index,element,record){
var catid = record.get('id'); << Value to pass
this.getNavigation().push({
xtype: 'panel',
title: 'A',
scrollable: true,
styleHtmlContent: true,
catid: catid,
layout: {
type: 'fit'
},
items: [
{
xtype: 'showSearchCategory',
}
]
});
}
My view in initialize
this.callParent(arguments);
var sto = Ext.getStore('allapp');
sto.clearFilter();
sto.filter('categoryid', this.getCatid());
And this Error message:
Uncaught TypeError: Object [object Object] has no method 'getCatid'
Have you made sure, your View has a function called getCadid? This is what the error message is trying to tell you. You would have to make sure there is a method available while initializing.
Another, possible simpler approach is to filter the store in the controller - which would be the better approach from my perspective. The View would be able to just care about how anything is displayed and the controller cares about what data to display.
You can use references and controls to wait for the view to finish loading and then filter the store (or wait for the user to activate custom filters, etc.):
Ext.define('myApp.controller.aController', {
extend: 'Ext.app.Controller',
config: {
refs: {
justAName: 'ViewName'
}
control: {
justAName: {
activate: 'onActivateView'
}
}
}
onActivateView: function () {...}
});
This is the basic stub for a controller listening to the activation of a specific view. You can just get your store in this function and filter it by all data available in the controller. To get data from the View, create a reference to it, and access it in the controller via for example:
var data = this.getJustAnotherName().getValue();
//having a reference to a textfield for example called justAnotherName
Given a simple Ext.List like the one in the Sencha docs, how can I make a new Panel or Carousel get "pushed" onto the screen when I click on one of the names?
http://docs.sencha.com/touch/2-0/#!/guide/list
I'd like to be able to have a button to navigate back to the main screen too.
You can achieve this using Ext.navigation.View. Here is a very simple application demonstrating this:
Ext.setup({
// onReady is when we can start building our application
onReady: function() {
// Create the view by just adding a config block into Ext.Viewport.
// We give it a reference of `view` so we can use it later
var view = Ext.Viewport.add({
// Give it an xtype of `navigationview` so it knows to create a NavigaitonView
xtype: 'navigationview',
// Define the list as its only item
items: [
{
xtype: 'list',
// Give it a title so the navigation view will show it
title: 'List',
// `itemTpl` is the template for each item in the list. We are going to create a store
// with a bunch of records, which each have a field called `name`, so we use that in our
// template
itemTpl: '{name}',
// Define our store
store: {
// Define the fields that our store will have
fields: ['name'],
// And give it some data for each record.
data: [
{ name: 'one' },
{ name: 'two' },
{ name: 'three' }
]
},
// Now we add a listener for the `itemtap` event, which is fired when a user taps on an item
// in this list. This event is passed various arguments in the signature, but we only need the
// record
listeners: {
itemtap: function(list, index, target, record) {
// now we have the record from the store, which was tapped. we now want to push a new view into
// the navigaitonview
view.push({
// Give it an xtype of panel
xtype: 'panel',
// Set the title to the name field of the record
title: record.get('name'),
// And add some random html
html: 'This is my pushed view!'
})
}
}
}
]
});
}
});
I've added inline comments so you know what is going on.
I also suggest you to ask questions over on the Sencha Forums as you will probably receive a much quicker response.
Here, i'm registering my app:
App = new Ext.Application({
name: "App",
launch: function() {
this.views.viewport = new this.views.Viewport();
}
});
This is the way i register new panels and components. I put each of them into seperate js files.
App.views.Viewport = Ext.extend(Ext.TabPanel, {
fullscreen: true,
tabBar: {
dock: 'bottom',
layout: {
pack: 'center'
}
},
items: [
{
xtype: 'cPanel'
},
{
xtype: 'anotherPanel'
}
]
});
// register this new extended type
Ext.reg('App.views.viewport', App.views.Viewport);
I added the other components in the same manner.
In one my components which is a list view, I want to change the container panel's activeItem with another panel when tappen on an item, like this: ( Viewport contains this container panel)
App.views.ListApp = Ext.extend(Ext.List, {
store: App.store,
itemTpl: "...",
onItemDisclosure: function(record) {
App.detailPanel.update(record.data);
App.cPanel.setActiveItem("detailPanel");
},
listeners: {
itemtap: function(view, index, item, e) {
var rec = view.getStore().getAt(index);
App.views.detailPanel.update(rec.data);
App.views.cPanel.setActiveItem("detailPanel", {type:"slide", direction: "left"});
}
}
});
App.views.detailPanel.update(rec.data);
But it says: can't call method "update" of undefined
I tried different variations on that line, like:
App.detailPanel.update(rec.data);
and i tried to give detailPanel and cPanel ids, where they were added to their container panel, and tried to reach them with Ext.get(), but none of these worked.
What is the problem here?
And any other advices would be appreciated.
Thanks.
The lazy way: give the panels ids and use:
Ext.getCmp(id)
The recommended way: Assign itemId to your panel and use:
App.views.viewport.getComponent(itemId)
This will allow you to have more than one instance of the same component at aby given time, the first example is not valid cause you can only have a singular id in the DOM tree.
Also getComponent only works for components stored in the items collection.