I'm building an application using Ext Js MVC approach.
I have a couple of combos on different views bound to one store. The store is set to query: remote and autoLoad: false and loads its data from server.
The problem every time I change the view (the old view is destroed) and expand the combo, the store will reload its data. Is there any way to force the store to load its data only once ? When the store is once loaded it will not reload it again even the bound combo is destroed.
There are ways to do this on the combobox itself but I think the easiest way for you is to subscribe to the load event of the store and check if the store contains records, if so abort the loading.
store.on('beforeload', function(s){
return !s.count() > 0;
});
Related
I'm using the kendo MultiSelect with odata paging and using the angularJS integration. Populating the data from scratch works great. When I want to re-populate the data from initial data then I seem to have a problem.
Cause of the problem:
The data only gets populate from the initial or previous dataset. So, if I the paging size is 10 then only products that exist in the first page will be displayed as normal. All product that don't fall within the first page will just not be displayed.
Possible workarounds:
Increase the page size. I have used this on other pages where the results are quite small. However this is not a realistic work around as we are expecting much bigger datasets in the future ( hence using odata in the first place)
Was thinking we could possibly do some sort of initial sorting. However this could also be slow and could still be a problem if there were more items selected than exist in the first page.
Ideal solution
Is there a way to tell kendo component to load all data based on current value? This will then build the required odata call and populate the component.
Example of the current issue:
http://dojo.telerik.com/ODaLe/2
I worked 2-4 hours to find a solution for this. Dunno if yall would like it, but it might help somebody, so I'd type it here. Following are the steps:
Step 1: Create the data source
First, setup the dataSource object which you would be using for reading remote data (for offline data, improvise by reading the API).
var dataSource = new kendo.data.DataSource({
dataType: "jsonp",
transport: {
read: {
url: options.source,
type: 'POST'
},
},
serverFiltering: true
});
Step 2: Load the selected items
This can be tricky as you need to have the selected item IDs on the client side. For me, I did it by adding a data-options-selected="1;3;9" attribute to my select element. Later, in my JavaScript, I split this attribute by ";" and retrieve an array of selected IDs. Lets say these values are in var valuesArray;
Once we have an array of selected IDs, we need to read them from the data-source. In my case, it was remote, so I ran a dataSource.read() with filters as under:
dataSource.read({
filter: {
logic: 'and',
filters: [
{
field: options.dataValueField,
operator: 'equals',
value: options.value
}
]
}
});
On the server side, this should return an array containing the items having the given identifiers. Thus, we now have those items on the client-side as well.
Step 3: Set values for the widget
Now that the value related data is loaded, we can set the values for the widget using the values() method. Here, $el is the jQuery object representing the select element which I was using for multiSelect.
var oWidget = $el.data('kendoMultiSelect');
oWidget.value(valuesArray);
That's it! One multiselect widget pre-loaded with values, ready to rock and roll. Served my purpose. Dunno if any short-cuts exist.
When using Kendo with Angular, you want to use the k-rebind attribute to refresh the pulldown options + update the picker with the values in your $scope.countries object when it changes.
If you want like the picker to update when $scope.products changes as well, you can initialize the picker using a k-options attr pointed to an object in your controller, and set the k-rebind to that object.
This kendo tutorial provides a useful example, also using odata paging.
http://docs.telerik.com/kendo-ui/web/multiselect/how-to/AngularJS/pre-select-items
I'm working on a ExtJS.Grid that uses a Ext.data.Store with jsonp proxy and Ext.PagingToolbar to control paging. It's all working fine.
But some users are complaining that they further browse pages, leave the grid, and when they come back they are back to page 1. They want "the grid to remember" the page they were and starts on it.
I use a Ext.onReady(function(){},false); to define all components and another Ext.onReady(function(){}); to create the grid with a store.loadPage(1); to make the first load after everything is done.
If I could listen to some event from the Ext.PagingToolbar, when a new load happens, and capture the page it was used, I could pehaps store it in some cookie or something, and retrieve it to load that page again.
I looked on http://docs.sencha.com/extjs/4.1.3/#!/api/Ext.toolbar.Paging and found no event that could be used. Anybody has any idea of where I could do it?
You can track the change event of the Ext.toolbar.Paging and remember the currentPage in a cookie.
pagingtoolbar.on('change', function(pb, pageData) {
Ext.util.Cookies.set('lastGridPage', pageData.currentPage, new Date('1/1/2016'));
});
And setup your grid to load that page on afterrender
grid.on('afterrender', function() {
var pageNumber = Ext.util.Cookies.get('lastGridPage') || 1;
grid.store.loadPage(pageNumber);
})
I have a data store and a grid. I add filters in the store and they work properly as I see the results in my grid. But once I disable all my filters aka clear them from my store I want to view all my rows in the grid without reloading them from a web service which is a kind of heavy task. All data is already fetched from the service and there is no need to reaload it again.
How can I do this? Is there some function in the store?
There already was a similar question with correct answer. In short, you need to call filter method without params after setting remoteFilter to false:
store.remoteFilter = false;
store.clearFilter();
store.remoteFilter = true;
store.filter();
Here is a jsfiddle: http://jsfiddle.net/8Gmtd/
I suspect that your grid's view is not refreshed. Try this:
mygrid.getView().refresh()
What is the best way to query unrendered components? I tried to query them as always using .query( '[group=abc]' ).
However this time, the components, having each group: abc, are not yet rendered, since they are used in an editable grid (first click it).
What I am trying to do is:
get data via Ajax for comboboxes
create an unknown number of comboboxes
put that Ajax data into each combobox
Problem: I want that boxes to be filled with the data on Ajax success
loading the data on Ajax success answer fails since I am missing a method to get my comboboxes via the property group=abc
loading the data on combobox creation fails too, since the Ajax success answer is not yet back
You will not be able to use ComponentQuery for unrendered components. You best bet is probably your last list item: Load the data into the combo stores when the combos are created. The key will be to mask the action that creates the combos (is this a grid row editor or something like that?) until the Ajax call is complete.
myComponent.setLoading(true);
Ext.Ajax.request({
//your request info here
success: function() {
//now unmask your component, allowing your combos to be created:
myComponent.setLoading(false);
//do other stuff here
}
});
I have a problem with comboboxes on my form.
The problem is that when I load form data (with form.loadRecord) sometimes comboboxes are empty even though I know that the model has the data.
When I look into Firebug I can see that the combobox stores are loaded after the record has been loaded. I thinks this is the reason – the combobox stores are loaded later then record is loaded.
This is how I set combobox stores:
//All stores have autoload:true configuration.
var possessionGroundsStore = Ext.create('path.to.store');
var vehicleTypesStore = Ext.create('path.to.store');
var usePurposesStore = Ext.create('path.to.store');
this.editView = Ext.create('path.to.view');
this.editView.getPossessionGroundsField().store = possessionGroundsStore;
this.editView.getVehicleTypeIdComboBox().store = vehicleTypesStore;
this.editView.getUsePurposeField().store = usePurposesStore;
//later
this.editView.loadRecord(record);
Is there a common way to solve this problem?
The only way I can see now is to use store.load callbacks in every combobox store
and then execute loadRecord after all stores were loaded, but it seems complex.
Any help?
UPDATE:
When form.loadRecord is called it internally calls field.setValue().
So, the point is: combobox store have to be populated before setValue is called.
If the store is not loaded you will see valueField instead of displayField.
The default config for comboboxes will trigger a store load when they get expanded for the first time after being created.
That will happen for any combobox unless you give it a queryMode: 'local' config. In other words the default combobox config almost always completes loading it's store after the component is created. For that reason, it seems strange to me that your combos are having a hard time with being loaded too late, maybe they are being loaded too early with autoLoad: true
However, I don't run into the same problem you have because I usually set-up my comboboxes with queryMode: 'local' and pre-load the stores for them right at the app initialization stage. I do that because my combo stores are usually all reference stores that could get used in many different views in my app. I don't recreate the store when I create a combo component, I just get a reference to the already existing and loaded reference store with Ext.getStore('ComboStoreId'). You could try setting up your app like that.
If you don't want to do that, you could also try removing the autoLoad: true config from your combo stores, then call yourComboStore.load() after you call loadRecord.