Query unrendered components - extjs

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
}
});

Related

Passing Data vs. Separate Request in AngularJS using ngResource

I'm new to angular and trying to figure out how best to accomplish this.
Say you have set up an ngResource factory to get a bunch of widgets . You return those widgets(GET /api/widgets) and display them on the page in a list.
Now say you can edit those widgets in a dialog box by clicking an edit button next to the object in the list. Is it better practice to pass the individual widget's data (that was already retrieved by the first $resource call) to the edit dialog, or simply pass an ID parameter to the dialog box and have it resolve it's own $resource call using a separate GET /api/widgets/:widgetID call.
The data wouldn't realistically change between loading the list and clicking the edit button, so it doesn't need to be synced to the exact second. Both of these requests would come from the same factory, but the question is if you should store the data and pass it, or execute a separate request.
I don't see a reason to fetch it again, I would just reuse the object.

Kendo multiselect populate previously selected items using odata with paging. (AngularJS)

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

ExtJs determine visibility on form load

In Extjs 3.4 I have a fairly large form that is being populated from an ajax call via someForm.getForm().load({url: someplace, etc}) which is working flawlessly. The problem I can't seem to get around though, is that there are several comboboxes and checkboxes that determine if another field is visible and allowBlank.
As per the answer on a similar question I have tried using the actioncomplete event on the form but the fields do not have values at that point. I've also tried using the success event of the load() call but get the same issue.
Is there any other ways of getting this functionality from the form.load() call?
Edit - here is my load call:
var panel = Ext.getCmp('someFormID');
panel.getForm().load({
method: 'GET',
url: 'ajax_get_request.aspx?id=' + id,
success: function (form) {
// This will error: object is null or undefined
alert(form.findField('fieldID').getValue());
}
});
I'm relatively new to Extjs so maybe I'm just missing something here...
Not sure why hooking into success callback of Ext.form.BasicForm.load() fails for you, but I can propose an alternative approach.
I usually use explicit Ext.Ajax.request() call to load data into Ext.data.Record. Then in request()'s success callback I load data into form using Ext.form.BasicForm.loadRecord(). If you need to act upon loaded values, you can do it in the same callback.
I do it this way, because I like to have original values from the server stored somewhere aside.

how to do auto fetch in backbone

I have a collection of models I fetch from a REST API every 10 seconds. (collection.fetch() every 10 seconds with a timer).
The user can also edit the model in a dialog box and click Save going back to the table of models.
How do I prevent cases where the user saves a model in a dialog and the auto fetch exactly comes back with a stale model so the model stays with the stale data until the next auto fetch.
Two suggestions:
Use collection.fetch({ update: true }) - that way models will only be add/remove/change'd rather than recreated on each fetch.
When the model is edited via the your dialog box, only save() the specific attributes that the user changed, like model.save(changedData, { patch: true }); -- using this patch behavior will make sure you're only sending the attributes that were just changed. Then your server can respond with the other recently-changed attributes, and all should be fine.

the extjs component refresh

I have several extjs components in my page, the chart, gird ,formPanel and ect, and now I meet some problems about the refresh of them, take the gridPanle for example:
This is the grid codes:
var myStore=new Ext.data.JsonStore({
autoLoad:true,
fields:['name','age'.....]
});
var grid = new Ext.grid.GridPanel({
stroe:myStore,
colums:myColumns
//....other config
});
When the reload event of the stroe if acted(Triggered by user),the store will get new data from the server side, the the grid panel refresh, this is fine,
however sometimes the data from the server is null(for example, there is not data found according to the request from the client),if so, the grid panel also hold the data of last requst,
how to make the grid refresh (show nothing) and show something to user that no data found?
So are other components in my page,most are some charts.
I have thought use add a handler to handle the event of the refresh of the component,before it refresh, check the store, if the store is null, then do something,howeverI found that I can not get the store of a component,also their event are different,for eample:
For the GridPanle,there is a event of beforerender
http://dev.sencha.com/deploy/dev/docs/?class=Ext.grid.GridPanel
For a chart, there is a event of beforerefresh
http://dev.sencha.com/deploy/dev/docs/?class=Ext.chart.Chart
So use the render or refresh?
Any ideas?
a "null" response from the server should generally be considered an error.
In your grid example, if nothing matches, there should be some representation of a record set with zero records. For a typical JsonStore, the response should look like this:
{ total:0, items:[] }
(assuming a totalProperty of "total", and a root of "items")
That way, it's still a valid response (even if it's not null).
If your server is sending back "null", or an empty raw response (a zero-length string), JsonReader doesn't know how to handle it, and errors or bails.

Resources