This is a migrated thread and some comments may be shown as answers.

Client-Side EventArgs are Mutable

4 Answers 42 Views
Grid
This is a migrated thread and some comments may be shown as answers.
Brett
Top achievements
Rank 1
Brett asked on 13 Nov 2014, 08:42 PM
I'm posting this for future reference and for general discussion.

In my implementation, I'm using ITemplate for custom GridItemTemplateColumns and assigning Javascript Method Names to the ClientEvents of Rad<Controls> that are "InitiatedIn" (ITemplate Implementation Method) my RadGrid, additionally, I've assigned DataKeys & ClientDataKeys in the page markup of the RadGrid Control.

The concept is thus to get the ClientDataKeys from the Telerik.Web.UI.GridDataItem (Client-Side) using the eventArg passed to it. I successfully did this, but discovered that the eventArg is mutable, which was unexpected.


Here is a partial example to follow on:

01.//C# (MyCustomGridItemTemplateColumn.cs file)
02.public class MyCustomGridItemTemplateColumn : ITemplate
03.    {
04.        public event RadComboBoxSelectedIndexChangedEventHandler OnMyControlSelectedIndexChanged;
05. 
06.        public string ClientHandlerMethod = "MyLibrary.UI.MyControl.OnMyControlChanging";
07.        public string ColumnName { get; private set; }
08. 
09.        public MyCustomGridItemTemplateColumn(string ColumnName)
10.        {
11.            this.ColumnName = ColumnName;
12.            this.OnMyControlSelectedIndexChanged += MyControlGridItemTemplateColumn_OnMyControlSelectedIndexChanged;
13.        }
14. 
15.        //Exposes the event to be handled on the codebehind
16.        void MyControlGridItemTemplateColumn_OnMyControlSelectedIndexChanged(object sender, RadComboBoxSelectedIndexChangedEventArgs e) {}
17.         
18.        public void InstantiateIn(Control container)
19.        {
20.            RadComboBox cbMyControl = new RadComboBox();
21.            cbMyControl.ID = "cbMyControl_" + ColumnName;
22.            cbMyControl.DataBinding += cbMyControl_DataBinding;
23.            cbMyControl.SelectedIndexChanged += cbMyControl_SelectedIndexChanged;
24.            cbMyControl.OnClientSelectedIndexChanging = @"function(sender, e){e._cancel = true;console.log('MyControl [IndexChanging] => %o %o', sender, e);}";
25.            cbMyControl.OnClientSelectedIndexChanged = @"function(sender, e){console.log('MyControl [IndexChanged] => %o %o',sender, e);}";
26.            cbMyControl.EnableViewState = false;
27.            container.Controls.Add(cbMyControl);           
28.        }
29. 
30.        void cbMyControl_SelectedIndexChanged(object sender, RadComboBoxSelectedIndexChangedEventArgs e)
31.        {
32.            this.OnMyControlSelectedIndexChanged(sender, e);
33.        }
34.         
35.        void cbMyControl_DataBinding(object sender, EventArgs e)
36.        {
37.            RadComboBox cbMyControl = (RadComboBox)sender;
38.            //GridDataItem container = (GridDataItem)cbMyControl.NamingContainer;
39.            //MyClassObjectModel model = (MyClassObjectModel)container.DataItem;
40. 
41.            cbMyControl.Items.Add(new RadComboBoxItem("Please Select", "NotSet"));
42.            cbMyControl.Items.Add(new RadComboBoxItem("First Choice", "1019q231"));
43.            cbMyControl.Items.Add(new RadComboBoxItem("Second Choice", "21vc3131"));
44.            cbMyControl.Items.Add(new RadComboBoxItem("Third Choice", "34Af3343"));
45. 
46.            cbMyControl.OnClientSelectedIndexChanging = String.Format(@"function(sender, e){{ e._cancel = !({0}(sender, e));{1}}}",
47.                ClientHandlerMethod,
48.                @" console.log(""MyControl [IndexChanging] %o %o "", sender, e);"
49.                );
50.        }
51.}


Now my library Example

01./* JS - Handler.js file */
02.(function(window){
03.window.MyLibrary = {
04.     "UI" : {
05.         "MyControl" : {
06.       "OnMyControlChanging" : function (sender, e) {
07.            var arg = MyLibrary.Common.GetDataKeyValues(e); }
08. }
09.  },
10.     "Common" : {
11.         "GetDataKeyValues" : function(e) {
12.             var max = 4;
13.             var iteration = 0;
14. 
15.             var result = {
16.              "FirstKeyID": {},
17.              "SecondKeyID": {},
18.              "ThirdKeyID": {}
19.             };
20. 
21.             var gridTableView = e.get_item();
22.             iteration = 0;
23.             while (!(gridTableView instanceof Telerik.Web.UI.GridTableView) && !(iteration >= max)) {
24.               gridTableView = gridTableView.get_parent() || gridTableView; //null check on get_parent()
25.               iteration += 1;
26.             }
27. 
28.             gridTableView.get_dataItems(); //e has now been mutated; the results of this method call do not matter
29. 
30.             var gridDataItem = e.get_item();
31.             iteration = 0;
32.             while (!(gridDataItem instanceof Telerik.Web.UI.GridDataItem) && !(iteration >= max)) {
33.               gridDataItem = gridDataItem.get_parent() || gridDataItem; //null check on get_parent()
34.               iteration += 1;
35.             }
36. 
37.             result.FirstKeyID = gridDataItem.GetDataKeyValue("FirstKeyID");
38.             result.SecondKeyID = gridDataItem.GetDataKeyValue("SecondKeyID");
39.             result.ThirdKeyID = gridDataItem.GetDataKeyValue("ThirdKeyID");
40.        
41.             return result;
42.         }
43.      }
44.};
45.}(window));

 
 
 





4 Answers, 1 is accepted

Sort by
0
Brett
Top achievements
Rank 1
answered on 13 Nov 2014, 09:13 PM
I suppose I forgot to mention that:
 e.get_item().get_parent().get_parent() is an instance of GridTableView (at first).

after calling get_dataItems() on it.

e.get_item().get_parent().get_parent() is no longer an instance of GridTableView, it becomes an instance of GridDataItem. that's where the whole immutable and mutable point comes into play. e can and will change.
0
Brett
Top achievements
Rank 1
answered on 13 Nov 2014, 10:18 PM
actually.. it isn't really about e being immutable or not.. this is really about sender and sender.get_parent().
0
Accepted
Konstantin Dikov
Telerik team
answered on 18 Nov 2014, 11:54 AM
Hello Brett,

The behavior that you are observing is due to the fact that the client-side data items of the grid are not created initially, but are created only after you call the get_dataItems method of the GridTableView. This is done for optimization purposes, because there are too many scenarios where the client-side items are not needed.

What you could do is to handle the client-side pageLoad event and call the get_dataItems() when the page loads, so you can get consistent behavior within your methods.


Best Regards,
Konstantin Dikov
Telerik
 

Check out the Telerik Platform - the only platform that combines a rich set of UI tools with powerful cloud services to develop web, hybrid and native mobile apps.

 
0
Brett
Top achievements
Rank 1
answered on 18 Nov 2014, 02:52 PM
thanks, I figured it was a performance consideration after reviewing some of your documentation on performance optimization, in general. 
Tags
Grid
Asked by
Brett
Top achievements
Rank 1
Answers by
Brett
Top achievements
Rank 1
Konstantin Dikov
Telerik team
Share this question
or