I have a page with a Kendo Grid. The read method from the dataSource calls a custom REST API which takes around 15 seconds and returns over 2,000 records.
When the user hits the "Export" button, by looking at the browser's Network tab, I see that the read method is triggered again.
Why isn't the export feature using the records that have already been loaded? I tried removing the pageSize and allPages properties but nothing has changed.
Is this Kendo's default behavior? If so, are there any workarounds so that the service is not called again?
HTML:
<div kendo-grid="grid"</div>
JS:
$scope.grid = {
dataSource: {
transport: {
read: {
url: "/...",
cache: false
}
},
schema: { ... },
pageSize: 20
},
toolbar: ["excel"],
excel: {
fileName: "xxx.xlsx",
allPages: true
}
};
When the allPages option is set to true and serverPaging is enabled,
the Grid will make a "read" request for all data. If the data items
are too many the browser may become unresponsive. Consider
implementing server-side export for such cases.
Docs
Server Side Export
Related
I have trouble getting the hideNoData() and showNoData() to work with the official highcharts-angular component (https://github.com/highcharts/highcharts-angular).
Here is a basic example in stackblitz: https://stackblitz.com/edit/angular-highcharts-zvkcys?file=app%2Fapp.component.ts
This is a simplified version. In my real project I'm fetching data async, and while loading I show my custom (not the one highcharts provides) loading indicator. So initially I want to turn off the no Data Message but once the result comes back, depending on the result I might need to show the no Data Message.
I already tried using the [(update)]="updateFlag" on the chart component to trigger a change after calling hideNoData() but with no effect. Same goes for update(), reflow() or redraw().
I even manually called detectChanges to force a digest cycle but also with no effect.
With Highcharts, I find it's important for my components to know the charts reference, you can use the supplied Output callback, in highcharts-chart to do this. In your component you can do:
public callback = this.chartCallback.bind(this);
Where chartCallback is:
public chartCallback(chart: Highcharts.Chart)
{
this.chart = chart;
}
HTML will look like:
<highcharts-chart [Highcharts]="Highcharts" [options]="options
[callbackFunction]="callback">
</highcharts-chart>
This allows us to grab the actual reference of the Highchart object, and use it like:
public hideNoData(): void
{
this.chart.hideNoData();
}
But ofcourse, once you have the reference to the chart, you can use it freely within the component.
See here for a full working example.
Additionally, if you never want the no data message to show. Then this might be your best route:
this.options = {
title : { text : 'simple chart' },
series: [{
data: [],
}],
noData: null
};
ok I found the solution. Apparently Highcharts cannot handle it in the same digest cycle. if i call
setTimeout(() => {
chart.hideNoData();
});
It works and is correctly hidden. However now it briefly flashes in the beginning, the solution to that is disabling the automatic message completely. In the chart options add following:
chart: {
events: {
load(): void {
this.hasData = (): boolean => {
return true;
};
},
},
},
I have a Kendo TreeView in which the parent nodes and children are all gotten at the same time.
Previously I was having the separate calls of which unless a Parent node was expanded, it did not call a query and pull that data into the parent node as children
Now that I have my data pulled all at once, I want to be able to do all sorts of CRUD operation in which if a node is created, deleted, sort order changed, then on Button click I want to send in all the data.
PROBLEM:
I noticed that in doing a console.log(mydatasource.data()); that I am seeing EMPTY children items.
Seems that if I expand ( or expand and collapse) THEN I get the children items to show up in chrome dev tools output
This is certainly a huge problem as I'm trying to send in the complete data and then run CRUD operations on all the data from essentially 3 database tables....
Why and how is this happening?
// show my data in chrome browser that is getting sent to mvc method
console.log(homogeneous.data());
Kendo TreeView
var homogeneous = new kendo.data.HierarchicalDataSource({
transport: {
read: {
url: serviceRoot + "/GetReportGroupAssignments",
dataType: "json"
}
},
schema: {
model: {
id: "Id"
,
children: "items",
hasChildren: "Id"
}
}
});
var treeview = $("#treeview").kendoTreeView({
expanded: true,
dragAndDrop: true,
select: onSelect,
dataSource: homogeneous,
dataTextField: "ReportGroupName"
,
template: kendo.template($("#treeview-template").html()) //,
}).data("kendoTreeView");
Try to set loadOnDemand to false.
Simple use case: I want to manually control when I load the store. When the store is loaded, I want the data to populate the list. However, I cannot get it to work.
When I set autoLoad to true on the store, it works. If I remove autoLoad, and add this to the view nothing happens.
List config:
{
xtype: 'list',
fullscreen: true,
disableSelection: true,
store: 'NewsStore',
itemId: 'newsList',
itemTpl: '<li><strong>{date} - {title}</strong><br/>{text}</li>',
plugins: [
{
xclass: 'Ext.ux.touch.PullRefreshFn',
pullText: 'Henter nyheter',
refreshFn: function () {
Ext.getStore('NewsStore').load();
}
}
]}
The listener on the panel will load the store:
listeners: {
painted: function () {
Ext.getStore('NewsStore').load();
}
}
I have tried to use the callback from the load method. I have tried to get the store from the list and update this, nothing works (the list is simply empty and does not display anything, even though I can see that the code is fetching the information). Any idea what I am doing wrong here?
You have to use setStore property to populate the data
var myStore = Ext.getStore('NewsStore');
Now access the list object and just
mylist.setStore(myStore);
I have the following example (http://jsfiddle.net/a473n/1/). The code is this:
Ext.state.Manager.setProvider(new Ext.state.LocalStorageProvider());
Ext.create('Ext.form.field.Checkbox', {
stateful: true,
boxLabel: 'Click me',
stateEvents: ['change'],
stateId: 'my-checkbox',
renderTo: document.body
});
When I use Chrome's debugger to view Resources and see local storage, I can see an entry for 'my-checkbox', but when I click the button that represents the checkbox in the page UI, I don't see the value of checked or unchecked being written to local storage. The value in local storage never changes. What gives?
The state data comes from the getState method. For checkboxes, it is inherited from AbstractComponent, and it merely saves the size of the component (see the code). So you'll have to provide your own implementation of this method if your wish is to save and restore the value.
Of course, there is a second step, you'll also have to override the applyState method to apply the extra things you'll be saving.
I've updated your fiddle to demonstrate this:
Ext.state.Manager.setProvider(new Ext.state.LocalStorageProvider());
Ext.create('Ext.form.field.Checkbox', {
stateful: true,
boxLabel: 'dasfasdf',
stateEvents: ['change'],
stateId: 'my-checkbox',
renderTo: Ext.getBody()
,getState: function() {
return {
checked: this.getValue()
};
}
,applyState: function(state) {
this.setValue(state && state.checked);
}
});
VoilĂ ! Value-wise stateful checkbox!
If you want to do this with something more involved than a checkbox, it would probably be a good idea to also call the parent of the overridden methods. Check the implementations for the actual components, to see if you need it.
When using the SnapshotStore, I have been unable to hydrate the "Name" property of the objects that are returning as part of my query. I get the correct OID for the project, but I would like to display the string name of the project instead of the OID. How can I go about doing that?
This is the code that I am using to query, but when I add the "Project" property to the Hydrate field, it does not seem to matter. If I comment out the hydrate line entirely, the state and resolution come back as unhydrated and not readable (by most people) so I know that it is at least working.
doSearch: function(query, fields, sort, pageSize, callback){
var transformStore = Ext.create('Rally.data.lookback.SnapshotStore', {
context: {
workspace: this.context.getWorkspace(),
project: this.context.getProject()
},
fetch: fields,
find: query,
autoLoad: true,
hydrate: ["State","Resolution","Project"],
listeners: {
scope: this,
load: this.processSnapshots
}
});
},
"We could not find the user-friendly form for the following: 'Project':7579240995" - is what I get when trying to include "Project" in the hydrate field.
I read somewhere that hydrate only works with drop down menus. Is that correct? And if so, how would I be able to show the project name easily for each object that the query is returning?
Unfortunately Project is not a hydratable field. In general the fields that can be hydrated are dropdown fields as you mentioned in your question.
The best way to do what you need is to use a Rally.data.WsapiDataStore to query for the projects in your current workspace and to build an in-memory map of OID to name.
var projects = {};
Ext.create('Rally.data.WsapiDataStore', {
model: 'Project',
autoLoad: true,
limit: Infinity,
fetch: ['Name', 'ObjectID'],
context: this.getContext().getDataContext(),
listeners: {
load: function(store, records) {
Ext.Array.each(records, function(record) {
projects[record.get('ObjectID')] = record.get('Name');
});
}
}
});