Loading ...
Sorry, an error occurred while loading the content.

Ajile :: Re: Import vs Include and async...

Expand Messages
  • iskitzdev
    Hi Mats, So sorry for the delayed response this go round. Your post got flagged as spam and I only noticed tonight! Not sure why that happened but here s my
    Message 1 of 4 , Nov 15, 2007
    • 0 Attachment
      Hi Mats,
      So sorry for the delayed response this go round. Your post got flagged
      as spam and I only noticed tonight! Not sure why that happened but
      here's my response.

      > I guess the issue I have with using AddImportListener (in every
      script file contributing to my "component") is that it somehow breaks
      the declarative nature of the code one would otherwise get if the
      Ajile directives could be used without it.
      >

      AddImportListener is only needed if you use code that immediately
      tries to use loaded, included, or imported code. If you define modules
      using the following pattern you won't need it:

      Import ("com.theirdomain.TheirModule");
      Import ("com.mydomain.MySpecialModule");
      Namespace ("com.mydomain");

      com.mydomain.MyComponent = function()
      {
      // Use TheirModule and MySpecialModule safely because this
      // code won't be executed unless you call
      // com.mydomain.MyComponent() or you create a new instance via
      // var mine = new com.mydomain.MyComponent();
      };//<-- no function execution

      Notice that MyComponent is defined as a function and NOT as an object
      literal or the result of an executed function as shown in your sample
      code i.e.

      MyComponent = function(){ return function(){} }();// <--execution

      If what you're developing truly is a component then it should be
      instantiated by something else when needed. If that's the case, only
      the program using your component will need to use AddImportListener.
      For example:

      Import ("com.mydomain.MyComponent");
      Namespace ("com.somedomain");

      com.somedomain.AProgram = new function()
      {
      var moduleName = "com.mydomain.MyComponent";

      Ajile.AddImportListener(moduleName, startProgram);

      function startProgram()
      {
      Ajile.RemoveImportListener(moduleName, startProgram);
      // use MyComponent
      }
      };//<- no function execution

      AddImportListener only exists because most browsers, with the
      exception of Opera, process scripts sequentially. That is to say
      browsers won't process a dynamically included script until the script
      that included it has been processed. Ajile uses dynamic script tag
      insertion (DOM or document.write depending on the browser's
      capability) which means that an included script is inserted into the
      DOM after the currently executing script and so won't be processed
      until after the current script returns.

      >I'm not clear on how wildcard imports or versioned namespaces work...
      >

      Wildcards work as follows:

      Import("com.mydomain.*"); // loads com.mydomain.js or com/mydomain.js

      com.mydomain.js contents:

      Namespace("com.mydomain");

      com.mydomain.Module1 = {/* definition here */};
      com.mydomain.Module2 = {/* definition here */};
      // etc...

      or

      Include("com.mydomain.Module1");
      Include("com.mydomain.Module2");
      // etc...

      Versioned namespaces are treated like any normal namespace except that
      they're loaded from a versioned file i.e.:

      Import("com.mydomain.*"); // loads com.mydomain.js
      Import("com.mydomain.*.0.9"); // loads com.mydomain.0.9.js

      >I'm not clear on how different entities are assumed to relate:
      package/module/file/directory/namespace/js-objects/functions etc, how
      they should be organized and what constraints Ajile poses here...
      >

      As far as Ajile's concerned, packages, namespaces and modules are
      essentially the same where loading, importing, and including are
      concerned. Directories are the developer's choice for organizing code,
      they may also choose to avoid directories and instead use
      fully-qualified module named files i.e:

      scripts/com.mydomain.MyModule.js

      instead of

      scripts/com/mydomain/MyModule.js


      >I have the feeling I am trying to use Ajile for things it might not
      be intended, e.g. declare "intra-module" dependencies (i.e. between
      files/objects/functions for a single "module")?
      >

      Sounds like you're using Ajile as intended, but examples would help
      clear up any confusion or miscommunication...

      >Btw, I found this an excellent article:
      http://www.ddj.com/architect/184415685
      >

      Interesting and looooong article :-) -- I'll have to read through the
      whole thing when I have more time. Thanks for the link.

      > For the moment being I have started taking a graded approach,
      meeting the requirements one by one (i.e. using namespaces, tracking
      dependencies, modularizing code, proper packaging.
      >

      Sounds like a smart approach.

      > At the same time I hope to get a better understanding of what
      services Ajile can provide!
      >

      Keep in touch. I'm sure my answers to your questions will give you a
      much clearer understanding of what Ajile services provides. Perhaps
      you'll inspire and/or discover other services as well...


      Best of luck,
      Michael


      --- In ajile@yahoogroups.com, Mats Eklund <mats.eklund@...> wrote:
      >
      > Thanks for your prompt reply!
      >
      > I guess the issue I have with using AddImportListener (in every
      script file contributing to my "component") is that it somehow breaks
      the declarative nature of the code one would otherwise get if the
      Ajile directives could be used without it.
      >
      > I like the idea of Ajile. I cannot say though that I have fully
      grasped all the aspects when it comes to better organizing and
      structuring javascript code/systems. The documentation of Ajile is
      nice, but it does not answer all the questions I have. For example,
      I'm not clear on how wildcard imports or versioned namespaces work,
      nor how different entities are assumed to relate:
      package/module/file/directory/namespace/js-objects/functions etc, how
      they should be organized and what constraints Ajile poses here. I have
      the feeling I am trying to use Ajile for things it might not be
      intended, e.g. declare "intra-module" dependencies (i.e. between
      files/objects/functions for a single "module")? Btw, I found this an
      excellent article: http://www.ddj.com/architect/184415685
      >
      > For the moment being I have started taking a graded approach,
      meeting the requirements one by one (i.e. using namespaces, tracking
      dependencies, modularizing code, proper packaging. dynamic loading is
      not yet really a requirement.) sticking to native language constructs
      w/o introducing another dependency on a framework. I guess some of
      these requirements need not be dealt with at javascript level, but can
      be dealt with using out-of-band mechanisms such as code annotations,
      build tools etc.
      >
      > At the same time I hope to get a better understanding of what
      services Ajile can provide!
      >
      > Best regards,
      > Mats
      >
      >
      > mikeizworkin <mikeizworkin@...> wrote:
      Hi Mats,
      > Glad you found Ajile; seems like you've got a pretty good grasp on how
      > to use it.
      >
      > You're right to use Include instead of Import for preserving the global
      > namespace; that's its main purpose.
      >
      > You're also right that Ajile loads modules in an asynchronous fashion
      > and that's why com.whatever.base.f1 is undefined as used in your
      example
      > code.
      >
      > I'm not sure I understand why you would prefer not to use the
      > Ajile.AddImportListener() method since it's specifically made for
      > resolving just this sort of problem. Using it you could rewrite your
      > code as follows:
      >
      > 1: Include("com.whatever.base");
      > 2:
      > 3: Ajile.AddImportListener("com.whatever.base",
      > 4:
      > 5: function() {
      > 8:
      > 9: // shorthand / quick reference
      > 10: var f1 = com.whatever.base.f1;
      > 11:
      > 12: Namespace("com.whatever.util");
      > 13:
      > 14: com.whatever.util.myFunc = function() {
      > 15: // do work using f1
      > 16: };
      > 17:
      > 18: });// end function and listener registration
      >
      > This approach ensures that an imported/included module is available
      > before it's used and is pretty unobtrusive; basically just wrapping
      your
      > code. FYI, I moved the Namespace statement to line 12 because it's
      only
      > needed at that point, but you could use it anywhere before line 3
      and be
      > okay; that would be even less obtrusive.
      >
      > If you can explain why the callback technique is not preferred maybe I
      > can suggest a more acceptable solution.
      >
      > Michael
      >
      > --- In ajile@yahoogroups.com, "mats.eklund" <mats.eklund@> wrote:
      > >
      > > Hi,
      > >
      > > I am new to Ajile, and need some help!
      > >
      > > I have a project/framework which I want to organize a bit better,
      > > including adding namespaces, explicit description of dependencies,
      > > dynamic loading, etc.
      > >
      > > I have many js files, organized into directories. Each file defines
      > > one or more "classes" and/or functions. Files and directories depend
      > > on each other in a hierarchical way. A few top-level classes
      > > constitute the framework's main API.
      > >
      > > So I introduced namespaces to avoid pollution of the global namespace
      > > (window).
      > >
      > > Then I added Import directives, so that dependencies become more
      > > explicit and files get loaded automatically after that the user loads
      > > a top-level file (driver).
      > >
      > > Now I noticed that the Import directive virtually reversed the effect
      > > of the namespace introduction, as all the names again appeared in the
      > > global namespace. I could get around this by using the Include
      > > directive instead. Is this the right approach?
      > >
      > > Then I noticed a problem which I guess has to do with the async
      > > behavior of Ajile. The following did not work:
      > >
      > > --- myFunc.js ---
      > >
      > > Namespace("com.whatever.util");
      > >
      > > Include("com.whatever.base");
      > >
      > > com.whatever.util.myFunc = function() {
      > >
      > > // shorthand / quick reference
      > > var f1 = com.whatever.base.f1;
      > >
      > > return function() {
      > > // do work using f1
      > > };
      > >
      > > }();
      > >
      > > ------
      > >
      > > This does not work, since com.whatever.base.f1 is undefined at the
      > > point it is referenced. I accepted to use the AddImportListener
      at the
      > > level where I use the framework API, however, I'd prefer not to use
      > > this callback internally within the framework, i.e. in every
      > > file/module that includes/references other modules/files! ???
      > >
      > > Thanks!
      > > Mats
      > >
      >
      > [Non-text portions of this message have been removed]
      >
      >
      >
      >
      >
      > __________________________________________________
      > Do You Yahoo!?
      > Tired of spam? Yahoo! Mail has the best spam protection around
      > http://mail.yahoo.com
      > __________________________________________________
      > Do You Yahoo!?
      > Tired of spam? Yahoo! Mail has the best spam protection around
      > http://mail.yahoo.com
      >
      > [Non-text portions of this message have been removed]
      >
    Your message has been successfully submitted and would be delivered to recipients shortly.