[OPEN] [#507] Feature request - support for Static Direct Methods in custom Components

Page 1 of 2 12 LastLast
  1. #1

    [OPEN] [#507] Feature request - support for Static Direct Methods in custom Components

    Hi,

    As far as I know (unless it has changed recently - and I just double checked my book to be sure!), Custom Components (e.g. subclass of TreePanel or GridPanel etc) can only have instance Direct Methods, not static ones.

    If at all possible, it would be really useful. At least to me :)

    A good example of this is a custom TreePanel we use - the tree loader is the same wherever we use it (whether we use it via a WebForms page, a user control, or from deep inside a composite custom control, or even from an MVC View, etc).

    To avoid remembering to define a DirectMethod in many places, I currently define an ASHX as a nice/fast independent way to reuse the same loader regardless of where I use that custom TreePanel.

    For clean code organization (and easier "bundling" of a custom component) it would be nice to put such a "static" Direct Method onto my custom TreePanel (or custom TreeLoader) itself.

    It could even be possible to generate the Direct Method proxy as a prototype method on the JavaScript version of the Custom Control for us perhaps! (With your usual flexible options such as the option to call the client side method something else, etc.)

    This helps to keep things together a bit more. Especially when this is extended to include other functionality such as Add, Delete, Reload etc. One ASHX for each is what I currently do, and that is just for one custom component. In our app we have many custom components each with their own set of ASHX's, so we have an explosion of ASHX's.

    A static DirectMethod is slightly easier to unit test as well (though ASHX's are admittedly getting easier to unit test too)

    By the way, if the proxies had to be in its own "direct" namespace in that client object, that might be quite neat too.

    E.g if I had this:

    Ext.define('MyApp.CustomTreePanel', {
             extend: 'Ext.tree.Tree',
    
             etc...
    });
    It would be nice to to then have the method available either at

    MyApp.CustomTreePanel.MyDirectMethod
    or (as that could cause collisions, or look odd because of the PascalCase)

    MyApp.CustomTreePanel.direct.MyDirectMethod
    Then, if I have a tree instance, such as "this" or "myTree", I can simply do

    this.direct.MyDirectMethod({
        success: function() {}
    )
    or

    myTree.direct.MyDirectMethod({
        success: function() {}
    );
    Having "direct" on the client side is a tiny bit of branding for you but also maybe a neat separation of concerns/intent on the client side api, so to speak...?

    What do you think?
    Last edited by Daniil; Jun 10, 2014 at 2:59 PM. Reason: [OPEN] [#507]
  2. #2
    Hi Anup,

    Thank you for the suggestion!

    Though, I am afraid that a static DirectMethod cannot be encapsulated to a control. It might be defined on the page level only. Vladimir states it here:
    http://forums.ext.net/showthread.php...ll=1#post63709

    I would say meaning of a static DirectMethod is its lightweight. It is similar to ASP.NET page methods that don't go through the regular page lifecycle. A static DirectMethod doesn't go as well. It is operated by DirectRequectModule (IHttpModule) and it calls HttpApplication.CompleteRequest() which causes ASP.NET to bypass all events and filtering in the HTTP pipeline chain of execution and directly execute the EndRequest event. Well, it actually means that no controls are being recreated during a static DirectMethod request and, respectively, a DirectMethod (actual server method) cannot be retrieved from nowhere.
  3. #3
    Thanks for the details. Yeah, I guess the issue is the module wouldn't know what to call without providing yet more info (which is why I guess instance versions work - you have the control id. I guess one alternative is to supply yet more information such as namespace/class name for reflection purposes but that seems wrong/leaky/possibly a security risk as you might call almost anything if not done with care).

    I'll just stick with what I do now as it is not a terrible thing...

    You can close this. Thanks!
  4. #4
    Quote Originally Posted by anup View Post
    (which is why I guess instance versions work - you have the control id.
    There is one condition more - the control have to be recreated during a request. This example demonstrate this.

    Example
    <%@ Page Language="C#" %>
    
    <script runat="server">
        public class MyTextField : TextField
        {
            protected override void OnLoad(EventArgs e)
            {
                if (!Ext.Net.X.IsAjaxRequest)
                {
                    this.ResourceManager.AddDirectMethodControl(this);
                    this.Listeners.Change.Handler = "App.direct[this.id].OnChange(newValue);";
                }
            }
    
            [DirectMethod]
            public void OnChange(string text)
            {
                Ext.Net.X.Msg.Alert("DirectMethod OnChange", text).Show();
            }
        }
    
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!X.IsAjaxRequest) // Comment that to get the DirectMethod working
            {
                this.Form.Controls.Add(new MyTextField() { ID = "MyTextField1" });
            }
        }
    </script>
    
    <!DOCTYPE html>
    
    <html>
    <head runat="server">
        <title>Ext.NET v2 Example</title>
    </head>
    <body>
        <form runat="server">
            <ext:ResourceManager runat="server" />
        </form>
    </body>
    </html>
    Quote Originally Posted by anup View Post
    I guess one alternative is to supply yet more information such as namespace/class name for reflection purposes but that seems wrong/leaky/possibly a security risk as you might call almost anything if not done with care).
    Yes, it is the problem. We could render a full class name to client, but yes, it is a disclosure of code. I've just discussed that with Vladimir and we have a couple of thoughts how to implement it.

    1. Store "control id => class name" pairs on the server. Then, on a static DirectMethod request, we can retrieve a class name by id.

    or

    2. Create a ResourceManager's property like EnableInstanceStaticDirectMethods which would be false by default. Write in the property's summary that true causes rendering of a class's full name to client. Then that disclosure of code is going to be under a developer's responsibility.

    It is not something we are going to consider for v2, but I am creating a feature request for v3.
    https://github.com/extnet/Ext.NET/issues/507

    Hopefully, we'll have a chance to do that. Though, no promises:)

    Thank you for the feature request!
  5. #5
    Thanks for the reply. Yes, I was aware that you also need a control to be created during the request.

    Your example is actually quite a useful one for those who might benefit from DirectMethods like this in custom components where they don't need static ones (if the extra Post overhead is worth the trade-off - I can imagine in many cases it is!)

    Your two options for the static direct methods are interesting.

    The second option is risky as you note.

    For the first option to use a control id/class name pair on server it could be a problem too: for high use sites, the list of ids could grow quickly using up more memory (if control id is not fixed)? Perhaps use the component's xtype and the Direct proxy on the client side could send the xtype? Given these are for static direct methods, we don't need instance info like a control id to store against a class, but some class level info such as InstanceOf or XType?

    Still, am happy to wait for v3 for this. Your alternatives sound interesting. However, if it is going to make your architecture a bit more complicated or difficult to maintain then I would be happy if you did not do this. I don't know how many others do this kind of thing a lot or not. Although maybe it is a chicken-and-egg thing - if it is there maybe it might be used more and help people think about round tripping/performance etc?
  6. #6
    Quote Originally Posted by anup View Post
    for high use sites, the list of ids could grow quickly using up more memory (if control id is not fixed)?
    Sorry, I don't get it. Please clarify what you mean by "id is not fixed".

    Quote Originally Posted by anup View Post
    Perhaps use the component's xtype and the Direct proxy on the client side could send the xtype? Given these are for static direct methods, we don't need instance info like a control id to store against a class, but some class level info such as InstanceOf or XType?
    I think there might be an unlimited amount of controls with the same InstanceOf and XType. You always can extend some control without overriding those properties.

    Quote Originally Posted by anup View Post
    However, if it is going to make your architecture a bit more complicated or difficult to maintain then I would be happy if you did not do this.
    Well, at this point it looks achievable without big efforts and complications. Though, who knows what pops up on actual implementing.

    Quote Originally Posted by anup View Post
    I don't know how many others do this kind of thing a lot or not.
    To the best of my recollection you are the first who asked that:)

    Quote Originally Posted by anup View Post
    Although maybe it is a chicken-and-egg thing - if it is there maybe it might be used more and help people think about round tripping/performance etc?
    Maybe you are right.
  7. #7
    Quote Originally Posted by Daniil View Post
    Sorry, I don't get it. Please clarify what you mean by "id is not fixed".
    There are times when the id can be generated for a component if it is not specified manually. I use this in some scenarios where I am often creating/destroying components during ASHX requests where I can't specify a fixed id, and so I rely on the unique id generated by Ext.NET or Ext JS. Many users using such an app could result in lots of ids for the same type of component being mapped to the same static direct method?

    Quote Originally Posted by Daniil View Post
    I think there might be an unlimited amount of controls with the same InstanceOf and XType. You always can extend some control without overriding those properties.
    Good point. So at the moment it seems like using id is the best option...?
  8. #8
    Quote Originally Posted by anup View Post
    There are times when the id can be generated for a component if it is not specified manually. I use this in some scenarios where I am often creating/destroying components during ASHX requests where I can't specify a fixed id, and so I rely on the unique id generated by Ext.NET or Ext JS. Many users using such an app could result in lots of ids for the same type of component being mapped to the same static direct method?
    Thank you for clarifying.

    If an ID is generated by Ext.NET (i.e. on server), we could probably use that ID to map to a DirectMethod. As for ExtJS, it generates ids on client. I don't think we can use that ids to map, do you?

    As for a memory problem. I tend to agree, in a big application with very high amount of problem it might take some memory. But how much? Probably, it will be just strings to Types map, it should not take that much. What do you think? Maybe, I cannot comprehend the scale of possible Ext.NET usage:)

    Quote Originally Posted by anup View Post
    Good point. So at the moment it seems like using id is the best option...?
    At the moment, yes. Maybe, we will be able to come up with something better. I am also thinking about a possibility to render a control with an id of its DirectMethods and pass it to the server with a request. Then, possibly, there will be just a map of DirectMethods' ids to Types (where to find that DirectMethod). What do you think?
  9. #9
    Yes, I don't expect client generated ids to be anything server knows about. I shouldn't have mentioned Ext JS ids. Mistake :)

    I think we can at least try to live with the proposed solution and see how real the memory concern would be. Maybe it turns out to be small in the grand scheme of things.

    Your additional idea is also good. All these options can probably be wrapped up in the client proxy layer so developers don't need to remember to send such an id anyway, so that should be good.
  10. #10
    Quote Originally Posted by anup View Post
    Your additional idea is also good. All these options can probably be wrapped up in the client proxy layer so developers don't need to remember to send such an id anyway, so that should be good.
    Agree, we should find a way not to obligate a developer to remember that.

    I updated the Issue with a summary of our discussion. It would be nice if you can review I didn't forget something.
    https://github.com/extnet/Ext.NET/issues/507
Page 1 of 2 12 LastLast

Similar Threads

  1. [OPEN] [#48] GridPanel - Feature Request
    By adelaney in forum 2.x Legacy Premium Help
    Replies: 6
    Last Post: Nov 17, 2012, 1:20 AM
  2. Direct Methods and Custom Control
    By Zdenek in forum 1.x Help
    Replies: 0
    Last Post: Apr 19, 2012, 10:18 PM
  3. Replies: 13
    Last Post: May 16, 2011, 1:26 PM
  4. Feature Request
    By dsmith in forum 1.x Help
    Replies: 0
    Last Post: Jul 07, 2010, 8:19 PM
  5. Support for ExtJS 3.0 Feature
    By AlphonsoT in forum Open Discussions
    Replies: 2
    Last Post: Jul 13, 2009, 6:44 PM

Tags for this Thread

Posting Permissions