[CLOSED] Components created in a Direct Response do not always generate correct script

  1. #1

    [CLOSED] Components created in a Direct Response do not always generate correct script

    Hi,

    Consider this markup:

    <%@ Page Language="C#" %>
    <!DOCTYPE html>
    <html>
        <head>
            <title>Example</title>
        </head>
        <body>
            <ext:ResourceManager runat="server" Theme="Gray" />
    
            <ext:Button runat="server" Text="Get Server Time">
                <DirectEvents>
                    <Click 
                        Url="WebServices/ServerTimeService.asmx/GetServerTimeWindow" 
                        Type="Load" 
                        Method="POST" 
                        CleanRequest="true" />
                </DirectEvents>
            </ext:Button>
        </body>
    </html>
    This is the service:

    using System;
    using System.Web.Services;
    using Ext.Net;
    
    namespace Ext.Net2.Tests.Direct.WebServices
    {
        [WebService(Namespace = "http://tempuri.org/")]
        [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
        public class ServerTimeService : WebService
        {
            [WebMethod]
            public DirectResponse GetServerTimeWindow()
            {
                var window = new Window("Server time", Icon.Time)
                {
                    ID = "MyWindow",
                    Html = DateTime.Now.ToString(),
                    Hidden = true
                };
    
                // some condition makes us show it now
                window.Show();
    
                return new DirectResponse(window.ToScript());
            }
        }
    }
    This is the script portion of the output slightly pretty printed:
    Ext.net.ResourceMgr.destroyCmp("App.MyWindow");
    Ext.create("Ext.window.Window",{
      id:"MyWindow",
      height:100,
      html:"12/05/2012 00:01:57",
      renderTo:Ext.getBody(),
      width:200,
      title:"Server time",
      iconCls:"#Time"});
    MyWindow.show();
    The problem is the very last line.

    Because I have set the window to be hidden, it doesn't actually show. The reason is there is an error in the script that is generated. Although I have simulated a scenario where the window should be shown using window.Show();, the output creates MyWindow.show() instead of App.MyWindow.show().

    I see on the first line you are able to figure out the namespace is App and destroy the component first, so hopefully this means this last line can be fixed too?

    But this then got me wondering: as I understand it, the "App" namespace can be customzied in web.config and/or the resource manager and "App" is only the default. So
    • How will you know what namespace to use?
    • If the namespace for the client objects is defined on the ResourceManager on the originating ASPX page you would not know which one to use?


    For example, if I do this:

    <ext:ResourceManager runat="server" Theme="Gray" Namespace="CompanyX" />
    The script that is returned during the DirectEvent is still
    Ext.net.ResourceMgr.destroyCmp("App.MyWindow");
    Maybe a solution to this second part is to always have a known alias when you initialize your pages? For example, with the above CompanyX example, this is currently what your code produces:
    Ext.net.ResourceMgr.init({id:"ctl00",theme:"gray",ns:["CompanyX"]});
    But maybe it can do something like this:

    Ext.net.ResourceMgr.init({id:"ctl00",theme:"gray",ns:["CompanyX"]});
    Ext.net.App = CompanyX;
    I use Ext.net.App instead of App as it might be a bit "safer" (someone else doesn't accidentally create App, for example, and override all your stuff).

    Maybe this way you can then always safely use Ext.net.App.MyWindow in the above examples?
    Last edited by Daniil; May 14, 2012 at 10:48 AM. Reason: [CLOSED]
  2. #2
    Hi,

    About your sample, it is a bug. Widget should use default namespace 'App' instead empty namespace. It is fixed in SVN

    Now about namespace is defined in the page. As you understand, webservice doesn't have access to the page and doesn't know about new namespace.
    Therefore you have to set Namespace explicitly for dynamic control in webservice (there is no another way).
    Namespace="Ext.net.App"
    The single case when you don't need it, if namespace is defined in web.config and webservice belongs to the same web application. In this case, dynamic widget can read it from web.config

    So, if your page uses custom namespace then define Namespace explicitly for dynamic controls (if controls has access to ResourceManager of a page: like in webservice, http handlers, controller action or static methods)

    How will you know what namespace to use?
    If you don't know namespace then dynamic widdget doesn't know it also (dynamic widget is out of context page, maximum it can read namespace from web.config, if have access to it)

    If the namespace for the client objects is defined on the ResourceManager on the originating ASPX page you would not know which one to use?
    Sure, setting namespace for dynamic widgets is developer's obligation

    You mix widget rendering and methods calling. I don't like such scenario because you can always set desired config options without methods calling (for example, why don't you set Hidden value is based on the same conditions are used for Show method calling)
    Methods should be used for already rendered (on the client side) control (and rendering should not be done in the same request because as i said it is better to use config options)

    P.S. After SVN update you can use Render method, DirectResponse will collect scripts automatically
    [WebMethod]
            public DirectResponse GetServerTimeWindow()
            {
                var window = new Window("Server time", Icon.Time)
                {
                    ID = "MyWindow",
                    Html = DateTime.Now.ToString(),
                    Hidden = true
                };
    
    
                window.Render();            
                window.Show();
    
    
                return new DirectResponse();
            }
    Vladimir Shcheglov
    Sr. Developer
  3. #3
    Quote Originally Posted by Vladimir View Post
    About your sample, it is a bug. Widget should use default namespace 'App' instead empty namespace. It is fixed in SVN
    Super quick! Again, many thanks for that. Really appreciated.

    Quote Originally Posted by Vladimir View Post
    Now about namespace is defined in the page. As you understand, webservice doesn't have access to the page and doesn't know about new namespace.
    Therefore you have to set Namespace explicitly for dynamic control in webservice (there is no another way).
    Namespace="Ext.net.App"
    The single case when you don't need it, if namespace is defined in web.config and webservice belongs to the same web application. In this case, dynamic widget can read it from web.config

    So, if your page uses custom namespace then define Namespace explicitly for dynamic controls (if controls has access to ResourceManager of a page: like in webservice, http handlers, controller action or static methods)
    Ok, thanks. I didn't spot the Namespace attribute but that works fine, so thanks. As you note, if defining namespace in web.config then this is not really an issue (in production code that is what I do. I only happened to come onto this because of the sample I was using and also trying to create a tiny self-contained example, regardless of how someone has their web.config)

    Quote Originally Posted by Vladimir View Post
    Sure, setting namespace for dynamic widgets is developer's obligation
    I think that is a fair enough point. The only alternative I can think of to get around this is if Ext.net uses a predictable/always guaranteed JavaScript alias for the direct methods (per my first post); Although that would mean a second alias on the browser page, it would point to the real definition so would not be any overhead I don't think. That would mean a developer would not need to set it and you can always be sure a correct namespaced call is generated.

    However, having said that, for me that would probably be a low priority, as your point about developer's obligation is something I'd tend to agree with. I would imagine the normal use case is to define the namespace globally in web.config. If so, this particular issue should not appear too often I would hope and if it does, the developer has a way to address it.

    Quote Originally Posted by Vladimir View Post
    You mix widget rendering and methods calling. I don't like such scenario because you can always set desired config options without methods calling (for example, why don't you set Hidden value is based on the same conditions are used for Show method calling)
    Methods should be used for already rendered (on the client side) control (and rendering should not be done in the same request because as i said it is better to use config options)
    I agree with you here too - I was just trying to show a very small and contrived example; I took the Ext.Net.Default.aspx from NuGet as a basis and modified it to be a server time window via an ASMX call. However, in reality I would also normally prefer not to do method calling on external services. I can see how it might be useful with in-page DirectEvents sometimes where the intent is perhaps a bit different and assumptions about controls on the page and the state of the page can be made to some extent. I probably took it a bit too far applying it to off-page requests :)

    Quote Originally Posted by Vladimir View Post
    P.S. After SVN update you can use Render method, DirectResponse will collect scripts automatically
    [WebMethod]
            public DirectResponse GetServerTimeWindow()
            {
                var window = new Window("Server time", Icon.Time)
                {
                    ID = "MyWindow",
                    Html = DateTime.Now.ToString(),
                    Hidden = true
                };
    
    
                window.Render();            
                window.Show();
    
    
                return new DirectResponse();
            }
    That is cool. Thanks for that.
  4. #4
    Hi Anup,

    Could you clarify have all questions been answered here? Can we mark the thread as closed?
  5. #5
    Yes, you can mark as closed. Many thanks.

Similar Threads

  1. Replies: 0
    Last Post: Aug 05, 2012, 10:46 AM
  2. [CLOSED] Can I use Response object in a direct method call?
    By feanor91 in forum 2.x Premium Help
    Replies: 2
    Last Post: Jun 12, 2012, 11:50 AM
  3. Replies: 5
    Last Post: May 17, 2011, 8:38 AM
  4. Replies: 0
    Last Post: Aug 05, 2009, 9:48 AM
  5. Replies: 2
    Last Post: Apr 04, 2009, 11:09 AM

Tags for this Thread

Posting Permissions