Announcement

Collapse
No announcement yet.
X
  • Filter
  • Time
Clear All
new posts

    ViewLoader - Has anyone used it successfully?

    SmartGWT/Power/2.5p

    I'm trying to use the ViewLoader class to load additional UI components at runtime, but so far I've had very little success.

    My app puts up a modal dialog with a ViewLoader in it.
    From the Javadoc it seems that I should be setting the ViewURL to the path of the generated JS file (mystuff.nocache.js).

    I do this and the whole webpage (not just the modal dialog) goes white and everything disappears. The GUI Console says that all existing components now have a Position of 0,0

    If I replace the mystuff.nocache.js with a simple file that just has enough JS to create a canvas with a black background it work fine.

    The hint I get is that the Development Mode window reports "Unloading module strategy" (the main app)

    I've searched all over but there's almost no information or examples for ViewLoader

    #2
    A ViewLoader loads SmartClient JavaScript code, such as that produced by using the ScreenLoaderServlet. It does not load GWT-generated JavaScript code.

    It's not clear what problem you're trying to solve that led you to ViewLoader, but it's almost certainly not the right approach. So take a step back and explain the problem and people may be able to help.

    Comment


      #3
      I have an app with a SmartGWT based UI.

      At runtime, the app scans a folder and searches for jars/wars containing a specific class. It then loads these jar/war files as plugins.

      I want the plugin to be able to provide a SmartGWT Canvas that holds the Plugin's UI, including databound components.

      Since the ViewLoader's javadoc says "The ViewLoader component can be used to load new Smart GWT-based user interfaces into a running application" it sounded like the perfect thing. A Canvas that can contain an externally defined SmartGWT-generated UI.

      This seems to be reinforced by the HTMLFlow JavaDoc: "Smart GWT components should be loaded via the ViewLoader class"

      The JavaDoc also points to the SmartGWT Architecture page which has the section about Segmenting Large Applications. This also seems to fit what I'm looking for, but it references FileLoader, but its javadoc only talks about skins.

      I've been following every thread I can find, but I wasn't able to find anything that seemed like a closer fit than ViewLoader.
      Last edited by evanross; 22 Jul 2012, 22:07.

      Comment


        #4
        I've been looking at HTMLFlow/HTMLPane which has the advice: "To dynamically load Smart GWT components, use ViewLoader, never this mechanism (click here for why)." but the "click here" link doesn't work.

        Comment


          #5
          The ViewLoader can load new SmartGWT components expressed in .ui.xml files or as JavaScript.

          GWT itself imposes the limitation that it's hard to load separately compiled applications into a single application, because each uses separate obfuscation.

          You need *another* step back to reconsider why you are doing this - what are your goals. If you're looking at this for performance reasons, we would recommend abandoning it for the reasons listed under SmartGWT architecture.

          If you're trying to decouple or better parallelize two development teams, we would recommend that each team works on a separate GWT module but the final application just inherits all the modules and they are compiled together.

          If you really have a requirement that 3rd party modules are "plugged in" at runtime with no compile step, GWT is a poor technology for this architecture and you can see that most GWT threads on this end in no solution or a very bad hack. It's certainly trivially easy in SmartClient, and much more feasible with SmartGWT than just core GWT, and we have achieved this for certain customers, but we wouldn't recommend this path unless you're prepared for a major investment.

          HTMLPane/Flow with contentsType:"page" will allow you to load another GWT application as an IFRAME, but this can be very slow, and if you need to communicate across the frame boundary you will need to do so with low-level JSNI techniques which are complex and error prone.

          Comment


            #6
            Yes, I'm in the third category. I'm developing a runtime framework application. User supplied plugins will be developed and deployed later.

            The rest of my client's organization uses jQuery for their web UIs, so that's probably what will be used in the the long run. I'm creating the initial example plugins using SmartGWT, but due to the issues you've raised, the production plugins will undoubtedly use jQuery.

            Comment


              #7
              I was able to get the 'plugin' UI by using an HTMLPane. It actually went together fairly easily with only a few gotchas.
              Now I have to figure out how to have a datasource for the plugin so it can have databound components.

              Comment


                #8
                Actually, this whole issue isn't very hard to do technically, it's the lack of documentation and examples that cause the difficulty.

                Encapsulating a plugin's SmartGWT UI is easy:
                Code:
                                            final HTMLPane canvas = new HTMLPane();
                                            canvas.setContentsURL("PluginUrl"));
                                            canvas.setContentsType(ContentsType.PAGE);
                Attaching the plugin to the ISC Data Server was a little more complicated but not by much.

                When I scan the plugin jar for the plugin classes I also look for .ds.xml files (but not the ones in the ../sc/.. folders) and for each one I create a DataSource.fromXML(reader) and store it in a map.

                I declared
                Code:
                       DataSource.addDynamicDSGenerator(new DynamicDSGenerator()
                        {
                            @SuppressWarnings("synthetic-access")
                            @Override
                            public DataSource getDataSource(final String aId,
                                                            final DSRequest aRequest)
                            {
                                //mLog.error("DynamicDSGenerator: "
                                //+ aId);
                                final DataSource result = mDataSources.get(aId);
                                mLog.error("DSName "
                                           + aId + " results in " + result);
                                return result;
                            }
                        });
                to select the correct DataSource at runtime.

                It has taken me a couple of weeks of experimenting and chasing wild geese to get this small amount of code working.

                I hope that my small samples help other people overcome misleading documentation and lack of examples about how to piece these things together.

                Comment


                  #9
                  This is not a good approach for implementing "plugin" applications and not anything that any other user should copy. It results in multiple copies of the SmartGWT runtime being loaded, once per "plugin", which radically increases memory requirements and slows everything down.

                  The use of iframes also makes it really hard to communicate between the main application and plugin, and exposes you to a wide variety of browser bugs and memory leaks if you try to do this.

                  Rather than being misleading, the documentation doesn't recommend this approach because it's a really bad idea.

                  Comment


                    #10
                    The use of SmartGWT in the plugins is a short term solution in order to get something demonstrable.

                    After much consideration, it looks like our long goal will be to abandon GWT/SmartGWT and replace the App and Plugin UIs with a more flexible javascript solution.

                    Comment


                      #11
                      JavaScript is definitely the more flexible language if you want to have runtime loadable plugins. The static nature of GWT and lack of support for Java reflection make this much harder to accomplish.

                      If you switch to SmartClient, your server side code can be reused unchanged, and your client-side code translates directly (the API is one-to-one). You also don't need new licenses.

                      Comment


                        #12
                        We should also note - without porting over any of your SmartGWT UI code to SmartClient, you could right now have people author plugins as SmartClient applications and you would be able to load them via ViewLoader. This is possible because SmartGWT contains the SmartClient runtime.

                        This would eliminate the iframe and all the problems that introduces.

                        Comment

                        Working...
                        X