PDA

View Full Version : [CLOSED] Changing store read parameters in JavaScript



anup
Nov 12, 2014, 3:43 PM
Hi,

This post was close to what I was looking for:
http://forums.ext.net/showthread.php?21883-CLOSED-How-to-change-store-s-parameter-in-javascript-before-load

But my scenario is slightly different.

I have, for example, a category tree and a grid. The grid, also has a search box in a toolbar. Furthermore, there are various buttons and dialogs users can use to build complex search requests.

In Ext.NET 1 I used to update baseParams using store.setBaseParam() with various parameters, such as the id of the category, the search term, or other search criteria our dialogs help to build.

setBaseParam is kind of replaced with store.proxy.extraParams, and I think I can use that for my needs. However, as I understand, and per a different thread we discussed, extraParams will also be sent for update requests, not just read requests.

I would ideally like to just update the read parameters, but I see that Ext.NET generates a function that returns an object literal of the initial parameters I defined. Some of these are ones I want to update, and other parts of the grid UI may create new parameters to add to this set of read parameters as they are not always needed initially.

Am I missing a way to update only the read parameters?

My initial thoughts were along the following lines:

Currently Ext.NET will generate a readParameters function on Store similar to this:



readParameters : function (operation) {
return {
apply : {
"selectedCategoryId" : 13,
"selectedCategoryActivityId" : 2,
"searchActivityId" : 2,
"viewActivityId" : 2,
"view" : "gv_ProductInformation",
"includedCategoryIds" : "",
"excludedCategoryIds" : "",
"includedDocumentIds" : "",
"excludedDocumentIds" : ""
}
};
}


Yes, quite horrendous looking, but our search is complex :) And there are many more parameters I have removed here!

Now, if a user types a search, I want to add a "search" property. If they update the category they are looking at, I have the category id so I just want to update the "selectedCategoryId" property, etc.

Does readParameters need to be a function? It is not doing anything with the operation parameter. It seems like it could just be the object literal:



readParameters : {
apply : {
"documentType" : "ppm:Product",
"useAsRootConceptFilter" : false,
"relationshipId" : "",
"parentExternalId" : "",
"parentActivityId" : 0,
"selectedCategoryId" : 13,
"selectedCategoryActivityId" : 2,
"searchActivityId" : 2,
"viewActivityId" : 2,
"view" : "gv_ProductInformation",
"includedCategoryIds" : "",
"excludedCategoryIds" : "",
"includedDocumentIds" : "",
"excludedDocumentIds" : "",
"useIncludedDocumentsAsManualOrder" : false,
"documentType" : "ppm:Product",
"processMessages" : true
}
}
}


Then, any time I need to interact with the store, I can get the proxy and simply update the readParameters, using something like store.readParameters.search = "my search term";

Is that a possibility or have I misunderstood something? And if so, is there a better/alternative way I should approach this?

Thanks!

anup
Nov 12, 2014, 4:07 PM
I should add that sometimes I don't always call store.load immediately with just the search term, for example. This is because after the user has done a search, that search needs to be part of the permanent set of read parameters, because subsequent filters, category selections, sort etc, will also be applying the search as well.

This is why updating the extraParams works (with the drawback they are sent on updates too).

To make that search query permanent (until the user clears the search, for example) I would need to maintain an object of additional read parameters somewhere and pass that into the store.load method.

I also have to ensure this idea also works where existing parameters that I set up in the store are updated by the user. For that, I think it means that instead of having the apply parameters in the readParameters function I suppose I should be using ApplyMode of IfNotExists for each store parameter I initially set up (at least for the ones the user can change) to create applyIf parameters instead...?

While that may work, it seems unfortunate to have two places to track the read parameters - the readParameters method that you generate, and another object somewhere else which I must then make sure I pass into the call to store.load().

Is that the approach I should be considering, or is there something even simpler?

anup
Nov 12, 2014, 4:13 PM
Sorry for yet another consideration I missed out.

Looking at the Ext.NET 1.x code I am migrating, not only do I not call store.load/reload in these scenarios, I actually use the pager on the grid to change to page 1 (pager.changePage(1)), which picks up all the other parameters currently being tracked.

The reason I do this is, for example, the user may be on page 3 and then decide to perform a search or change a category; if I don't go to page 1, there may not be a page 3 for the new criteria.

Maybe I should not try to continue doing that? Maybe I should use store.load() and apply the first page to the list of parameters I am tracking...?

You can see this is beginning to get more complicated... :)

Daniil
Nov 13, 2014, 10:55 AM
Hi Anup,


Does readParameters need to be a function?

It is done to support dynamic parameters. For example,

<ext:StoreParameter Name="test" Value="App.TextField1.getValue()" Mode="Raw" />

If "readParameters" is not a function, then "App.TextField1.getValue()" would be executed once at the time of the Store creation. So, it would be not updated on each load request. Moreover, if it executes at the time of the Store creation, then it could result in a JavaScript error if the TextField1 is not created yet.


It is not doing anything with the operation parameter.

You could use it:) Though, I am not sure there is any use case for the "operation" argument in a StoreParameter's Value.

<ext:StoreParameter Name="action" Value="operation.action" Mode="Raw" />

Actually, the Store's BaseParams server property in v1 is also rendered as a function - "beforeLoadParams" and it behaves in the same way as v2 Parameters property does. The original ExtJS "baseParams" doesn't support dynamic parameters as well, but such dynamic parameters are very actual for Ext.NET. So, the Store's BaseParams server property doesn't mean a client side baseParams config option. IMO, the BaseParams server property has a wrong name. Though, it doesn't stop you to use a .setBaseParam() on client. And, as you said, it works well for you in v1. This retrospective overview is just for clarifying.

So, the current problem is the fact that there is no .setBaseParam() in ExtJS 4 and, respectively, in Ext.NET v2.

Yes, as far as I can understand it would be nice to have an API possibility to change the read parameters on the fly that is rendered by a Store's Parameters, but I don't see such a possibility.

Yes, I would also think about a Proxy's ExtraParams, but you are right, it is sent on each request - read and sync.

Finally, for your scenario I suggest you to implement it by your own. Please review the example.

A PagingToolbar is to easily cause a read request. There is also the Button to cause a sync request. You can review requests' parameters. It appears to be working as you need.

Example

<%@ Page Language="C#" %>

<%@ Import Namespace="System.Collections.Generic" %>

<script runat="server">
public List<object> MyData = new List<object>
{
new { test = "test1" },
new { test = "test2" },
new { test = "test3" },
new { test = "test4" },
new { test = "test5" },
new { test = "test6" },
new { test = "test7" },
new { test = "test8" },
new { test = "test9" }
};

protected void Store_ReadData(object sender, StoreReadDataEventArgs e)
{
List<object> data = this.MyData;
var limit = e.Limit;
if ((e.Start + e.Limit) > data.Count)
{
limit = data.Count - e.Start;
}
List<object> rangeData = (e.Start < 0 || limit < 0) ? data : data.GetRange(e.Start, limit);
e.Total = data.Count;
(sender as Store).DataSource = rangeData;
}
</script>

<!DOCTYPE html>

<html>
<head runat="server">
<title>Ext.NET v2 Example</title>

<script>
var onBeforeLoad = function(store, operation) {
if (operation.action === "read") {
operation.params = operation.params || {};
Ext.apply(operation.params, store.myReadParameters);
}
};
</script>
</head>
<body>
<form runat="server">
<ext:ResourceManager runat="server" />

<ext:GridPanel ID="GridPanel1" runat="server">
<Store>
<ext:Store
ID="Store1"
runat="server"
OnReadData="Store_ReadData"
PageSize="3"
AutoSync="true">
<Model>
<ext:Model runat="server">
<Fields>
<ext:ModelField Name="test" />
</Fields>
</ext:Model>
</Model>
<Proxy>
<ext:PageProxy>
<Reader>
<ext:JsonReader />
</Reader>
</ext:PageProxy>
</Proxy>
<CustomConfig>
<ext:ConfigItem Name="myReadParameters">
<ext:Parameter Name="param1" Value="param1 value" Mode="Value" />
<ext:Parameter Name="param2" Value="param2 value" Mode="Value" />
</ext:ConfigItem>
</CustomConfig>
<Listeners>
<BeforeLoad Fn="onBeforeLoad" />
</Listeners>
</ext:Store>
</Store>
<ColumnModel runat="server">
<Columns>
<ext:Column runat="server" Text="Test" DataIndex="test">
<Editor>
<ext:TextField runat="server" />
</Editor>
</ext:Column>
</Columns>
</ColumnModel>
<BottomBar>
<ext:PagingToolbar runat="server" />
</BottomBar>
<Plugins>
<ext:CellEditing runat="server" />
</Plugins>
</ext:GridPanel>

<ext:Button runat="server" Text="Change the param1" Handler="App.Store1.myReadParameters.param1 = 'param1 new value';" />

<ext:Button runat="server" Text="Cause a sync request" Handler="App.Store1.getAt(0).set('test', 'new');" />
</form>
</body>
</html>


Also you can implement a "setBaseParam" like function for:

App.Store1.myReadParameters.param1 = 'param1 new value';

Hope this all suites your needs.

anup
Nov 13, 2014, 11:11 AM
Hi,

Thanks for the detailed response, as always. I didn't appreciate that you can support dynamic parameters, and now you mention that, it makes perfect sense.

(I was also looking back in my Ext.NET 1 code and also saw I was doing similar thing with before load to add my parameters - I just missed that yesterday!)

Thanks for your example about myReadParameters. I was thinking along similar line this morning and was about to try it out and update this post depending on how it went, just before I received notification of your reply here :)

The way I was going to do it was override buildReadParameters and use it from there, but I think your suggestion of handling beforeload event is cleaner and prevents me missing any enhancements/changes/fixes you make to buildReadParameters in the future. Also, had I overridden buildReadParameters method, because I didn't realize you support dynamic properties for read parameters, I could have affected that without realising. I may have a think to see if that actually helps me in some way I didn't think of before :)

Thanks for your help again!

The extraParams approach I was using temporarily helped, but this will be a lot cleaner for me :)

Daniil
Dec 24, 2014, 9:45 AM
Here is a related Ext.NET v3 discussion.
http://forums.ext.net/showthread.php?49421