Using clientside ViewControllers (Javascript)

  1. #1

    Using clientside ViewControllers (Javascript)

    I have a decent amount of experience using ExtJS and switched over to Ext.Net several months ago and I can't seem to figure out if this is possible or not.

    I'm developing an application where responsiveness is a thing and doing a server roundtrip for every interaction is an absolute killer and since in many cases the data required is already in a store in the browser we use javascript for those cases. At the moment, we have separate Javascript files per view which are stored in a bundle and hook them up in the views using Listeners(l => ...).

    That works, but the downside is that it is reasonably brittle and as files are refactored it has happened more than once that functionality stopped working.

    Is there a possibility where I can define a ExtJS ViewController and add them to my application? In regular js I'd use the 'controller' config on components or define a controller and use the 'controllers' config on the Application object.

    Is this possible or this is a deliberate design choice of ext.net that I do not understand?
  2. #2
    Hi @PatrickMBS,

    Sorry for such a delay in answering and thank you for the question.

    First of all, some general information on the topic. ExtJS MVC is something that we would love to support thoroughly, but I would define the current status of support as an experiment. That is interesting, but in my memories you are the first how is interested in that functionality and asking something via forums. So, some work is done to support, but again, it was an experiment and difficult to say how far it is functioning. You might give it a try.
    Is there a possibility where I can define a ExtJS ViewController and add them to my application? In regular js I'd use the 'controller' config on components or define a controller and use the 'controllers' config on the Application object.
    There is <ext:App> component. As for a component's controller config option it might be done via CustomConfig.

    Example
    <%@ Page Language="C#" %>
    
    <!DOCTYPE html>
    <html>
    <head runat="server">
        <title>Ext.NET v3 Example</title>
    </head>
    <body>
        <ext:ResourceManager runat="server" />
    
        <ext:App
            runat="server"
            Controllers="controller1,controller2"
            LaunchHandler="alert('Launch');">
            <Launch>
                <ext:Button runat="server" Text="Click me">
                    <CustomConfig>
                        <ext:ConfigItem Name="controller" Value="controller1" Mode="Value" />
                    </CustomConfig>
                </ext:Button>
            </Launch>
        </ext:App>
    </body>
    </html>
    This example renders the following JavaScript:
    Ext.application({
        launch: function() {
            Ext.create("Ext.button.Button", {
                id: "ctl04",
                "controller": "controller1",
                renderTo: "App.ctl04_Container",
                text: "Click me"
            });
            (function() {
                alert('Launch');
            }).call(this)
        },
        controllers: ["controller1", "controller2"],
        name: "App"
    });
    Please let me know if this is helpful or not.
    Last edited by Daniil; Sep 28, 2015 at 9:45 AM.
  3. #3
    Hello Daniil,

    Thank you for your response. In the meantime I was transferred to a different project which until quite recently did not require any front-end part but alas, the moment has come that it requires a UI.

    ExtJS MVC is something that we would love to support thoroughly, but I would define the current status of support as an experiment. That is interesting, but in my memories you are the first how is interested in that functionality and asking something via forums.
    Perhaps my interest in the topic comes from me starting out with ExtJS and then migrating over to Ext.NET and having experienced the power of the ExtJS MVVM / MVC model makes me at times feel that there is too much going on in a single view in the sense that there is both UI definition and control logic.

    Since we work with ASP.NET MVC as well I re-wrote your sample code to make use of the fluent MVC builders. However, by doing this I ran into a few problems which I can't quite seem to work around. Here is my index.cshtml page:

    <!DOCTYPE html>
    <html>
    <head>
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta charset="UTF-8">
        <title>Titles everywhere</title>
    </head>
    
    <body>
        @(Html.X().ResourceManager())
    
        @(Html.X().App()
            .LaunchHandler("alert('meow');")
        )
    
        <div class="content" id="container">
        </div>
    </body>
    </html>
    Unfortunately, this does not seem to deliver the same output as your Webforms example. In fact, my HTML is empty, no 'meow' alert is displayed and the extnet-init-js contains only this:
    Ext.net.ResourceMgr.init({isMVC:true,theme:"crisp",locale:"nl-NL"});Ext.onReady(function(){});
    Any tips?
  4. #4
    I think that is a bug. Thank you for pointing out the problem. Created an Issue:
    https://github.com/extnet/Ext.NET/issues/910

    There is no easy generic fix for Razor engine, but, fortunately, there is quite an easy workaround:

    1. Marking an application as MVC manually by calling MvcResourceManager.MarkAsMVC(); in the beginning. I think it could be done in Global.asax.
    2. Placing Html.X().App() before Html.X().ResourceManager().

    Workaround
    <!DOCTYPE html>
    
    <html>
    <head>
        <title>Ext.Net.MVC v3 Example</title>
    </head>
    <body>
        @{
            MvcResourceManager.MarkAsMVC();
        }
    
        @Html.X().App().LaunchHandler("alert('Launch');")
    
        @Html.X().ResourceManager()
    </body>
    </html>
    Last edited by Daniil; Dec 19, 2015 at 12:12 PM.
  5. #5
    Thanks for very useful pointers Daniil. We're currently pretty understaffed and until this morning I hadn't had time to go and implement this. It works, but with a few caveats:

    1) The call to
    Html.X().App()
    should have a call to the
    AppFolder(string path)
    method to configure the location of the script files.

    2) By default Ext.Net assumes the application's name to be "App" so any controllers should use that as the root namespace. One of my colleagues decided somewhere during development that it would be a wonderful idea to just reference every object through the global App object(instead of using Ext.getCmp()) so changing the application root namespace is pretty difficult at the moment. Using globals is bad!

    3) In your example you added a CustomConfig -> ConfigItem("controller", "{controllerName}") on the button. According to the Sencha documentation that can either be a string, an object or a ViewController object. In the case the controller is an object extending ViewController it cannot be pre-loaded through the Controller() method in the App() call chain. ExtJs will generate an error saying
    g.doInit is undefined.
    . Deriving the controller from
    Ext.app.Controller
    solved that issue but now requires a call to
    this.control()
    to configure event handlers. No biggy. I'm not entirely sure if it is possible to properly configure ViewControllers on an Ext.Net view because those are not loaded in the Controllers section of the application. In regular ExtJs these would reside in the same folder as the view so I'm going to see if the same goes of Ext.Net or if I can mirror the MVC view folder structure in the scripts folder (a la App/view/<viewname>/{viewcontroller}.js ).

    I do have one final question that is somewhat unrelated to my previous questions in this post. I've used both ExtJs and Ext.Net and I found that both of them are really useful in specific scenarios. I found Ext.Net to be particularly useful in developing small multi-page applications where re-use of .NET models on pages made development a breeze and significantly faster than developing it in ExtJs. However, in large(r) single page applications Ext.Net appears to become a limiting factor on both development speed and maintainability of the application. Especially the mixing of Javascript in the views, the use of the ModelState in Controllers and the lack of being able to compile all the views into a single script makes ExtJs significantly more robust for large apps.

    Was Ext.Net designed with the idea of being able to develop large single-page applications or was it specifically meant to develop smaller applications?
    Last edited by PatrickMBS; Dec 16, 2015 at 11:09 AM.
  6. #6
    Using ViewControllers is quite possible under the condition that all the javascript files are pre-loaded. This can be done by adding every single file into the main layout page or by using bundles. If the files aren't pre-loaded ExtJs/Net will attempt to load a nameless .js file in the root url.

    In my case I have the following file structure:
    ~/Views/<various views in sub-directories>
    ~/Views/Orderlines/Create.cshtml
    
    ~/Scripts/app/view/orderline/OrderlineEditorController.js
    ~/Scripts/app/<files following ExtJs conventions>
    
    ~/Scripts/application/<various non-ExtJs structured javascript files referenced from the views>
    I have a bundle that contains both the ~/Scripts/application and the ~/Scripts/app/ folders. Referencing a ViewController is then possible using the CustomConfig section:
    .CustomConfig(cfg => cfg.Add(new ConfigItem("controller", "orderlineeditor")))
    Edit:
    Actually, this does not work due to the generated ExtJs code. I have defined my listeners in my view like this:
    .Listeners(l =>
    {
        l.AfterRender.Fn = "afterRender";
    })
    Which results in the following Javascript being sent across the wire(I used FireFox's Network panel to inspect the sent json):
    listeners:{afterrender:{fn:afterRender}}
    The correct Javascript should in this case be:
    listeners:{afterrender:"afterRender"}
    This particular screen is opened through a DirectEvent section in another View:
            .DirectEvents(de =>
            {
                de.RowClick.Url = Url.Action("Edit", "OrderLine");
                de.RowClick.Before = "extraParams['id'] = o.control.selection.data.Id;extraParams['flightId'] = getSelectedFlightId();";
            })
    Is there a way for me to hook into the DirectEvent pipeline and process the returned Json myself? Because it would be wunderbar if I could take the returned Json, inspect it to find a 'controller' tag and if that is the case, process all listener blocks and strip out {fn: xxx} and replace them with proper syntax.
    Last edited by PatrickMBS; Dec 17, 2015 at 12:19 PM.
  7. #7
    Thank you for that very detailed feedback.

    Was Ext.Net designed with the idea of being able to develop large single-page applications or was it specifically meant to develop smaller applications?
    I believe it was and many large single-page applications have been developed and developing with Ext.NET.

    But it doesn't mean everything is ideal in the design and there is no room for improvements:)

    It looks like the main problem here that Ext.NET doesn't support ExtJS MVC. As I said previously:

    ExtJS MVC is something that we would love to support thoroughly, but I would define the current status of support as an experiment. ... So, some work is done to support, but again, it was an experiment and difficult to say how far it is functioning.
    According to your feedback it is now obvious that the current support is now quite ready to go, at least. I cannot say if we get it fully incorporated ever, but definitely it is something we hope to support eventually.

    and the lack of being able to compile all the views into a single script
    Yeah, it would be great to have in Ext.NET! Interesting, that a similar question has been asked by another member regarding .ascx in this thread:
    http://forums.ext.net/showthread.php?60254

    That is probably all that I can say in this thread. Yes, you have a few specific questions/problems, but discussing them in this same thread will make a mess here. I mean any specific issue is worth to create an individual thread for. The more specific an issue is the more chances we'll be able to help.

    P.S. Meanwhile, is that something you might be interested in?
    http://forums.ext.net/showthread.php...-Ext-NET-hires!

Similar Threads

  1. Replies: 2
    Last Post: Jul 10, 2012, 8:09 PM
  2. Replies: 2
    Last Post: Mar 19, 2012, 8:55 PM
  3. store filter clientside
    By Richardt in forum 1.x Help
    Replies: 2
    Last Post: Aug 13, 2010, 4:12 PM
  4. How to add Clientside validation?
    By speddi in forum 1.x Help
    Replies: 2
    Last Post: Jun 01, 2010, 1:09 AM
  5. ClientSide to grouping gridpanel
    By stephan1985 in forum 1.x Help
    Replies: 1
    Last Post: Feb 22, 2010, 11:57 AM

Posting Permissions