javascript - Why is YUI.add required when specifying YUI modules and if it is required how can non-YUI modules work? -


we use yui3 loader manage loading our javascript , css files. part of bootstrap js code on each page, have following:

yui({   ...   groups: {      ...       mygroup: {          modules: {              "my-module": {                  ...                  path: "mymodule.js",                  requires: [ "yui-base" ]              },          }          ...      }   } }).use("my-module", function (y) {     y.mymodule.dostuff(); }); 

mymodule.js has following:

yui.add('my-module', function (y) {     y.mymodule = function () {         ...         _validator: y.lang.isstring     }; }, '3.4.0', {     requires: [ "yui-base" ] }); 

yui claims here loader can used non-yui3 "modules" given have dependencies specified in configuration. give following example module configuration yui2 group:

       yui2: {            combine: true,            base: 'http://yui.yahooapis.com/2.8.0r4/build/',            combobase: 'http://yui.yahooapis.com/combo?',            root: '2.8.0r4/build/',            modules:  { // 1 or more external modules can loaded along side of yui                yui2_yde: {                    path: "yahoo-dom-event/yahoo-dom-event.js"                },                yui2_anim: {                    path: "animation/animation.js",                    requires: ['yui2_yde']                }            }        } 

this suggests yui smart enough load , run yui2's animation.js after yahoo-dom-event.js has loaded , run.

what don't understand is, if works non-yui modules, how come have wrap own modules yui.add , redundant requires list (since requires specified in configuration)?

i tried dropping add wrapper (i replaced (function (y) { /* module content */ })(yui);), lead js error on page load: y.lang undefined. thus, seems somehow without wrapping add() call script getting executed before base yui script y.lang defined. however, if case, won't problem non-yui modules (which don't call yui.add())?

it's important distinguish between custom modules utilize yui3 features (sandboxed y.lang, etc) , external code.

in first case, yui.add() wrapper necessary, because sandbox y variable isn't available outside module callback (the second argument yui.add()). repetition of module configuration unfortunately necessary in hand-written modules due constraints within y.loader (where combo-loading magic happens). modules employ yui's build tools have wrapper , metadata added automagically.

with external code, need provide fullpath config property, , yui right thing. internally, yui knows when given <script> request finishes, , associates success configured module name.

to simplify things, i'll using yui.applyconfig demonstrate config bits. using that, can create number of yui sandboxes (via yui().use(...)) config mixed in, instead of repeating on place.

yui.applyconfig({     "modules": {         "leaflet": {             "fullpath": "http://cdn.leafletjs.com/leaflet-0.6.4/leaflet.js"         },         "my-leaflet-thing": {             "path": "path/to/my-leaflet-thing.js",             "requires": [                 "base-build",                 "node-base",                 "leaflet"             ]         }     } }); 

my-leaflet-thing.js looks this:

yui.add("my-leaflet-thing", function (y) {     // safe reference global "l" provided leaflet.js     var l = y.config.global.l;      y.myleafletthing = y.base.create("myleaflet", y.base, {         initializer: function () {             var id = this.get('node').get('id');             var map = l.map(id);             // etc         }     }, {         attrs: {             node: {                 getter: y.one             }         }     });  // third argument version number, // doesn't affect right }, "1.0.0", {     "requires": [         "base-build",         "node-base",         "leaflet"     ] }); 

given setup, since requires non-asynchronous library, can safely this:

yui().use("my-leaflet-thing", function (y) {     var instance = new y.myleafletthing({         "node": "#foo"     }); }); 

note: if external file dynamic loading of own (e.g., async google maps api), yui aware of initial request success, not entire chain of files loaded. address this, you'll need use querystring callback argument in fullpath config, associated globally-exposed callback in module requires it.

in these cases, it's better internal y.use() (note sandbox variable) better encapsulate required globals.

config:

yui.applyconfig({     "modules": {         "google-maps-api": {             "fullpath": "http://maps.googleapis.com/maps/api/js" +                             "?v=3&sensor=false&callback=initgmapsapi"         },         "my-google-map-thing": {             "path": "path/to/my-google-map-thing.js",             "requires": [                 "base-build",                 "node-base"             ]         }     } }); 

my-google-map-thing.js:

yui.add("my-google-map-thing", function (y) {     // publish custom event fired global callback     y.publish('gmaps:ready', {         emitfacade: true,         fireonce: true     });      // private sentinel determine if y.use() has been called     var isused = false;      // expose global function matches "callback" parameter value     y.config.global.initgmapsapi = function () {         // y.config.global.google available         y.fire('gmaps:ready');     };      y.mygooglemapthing = y.base.create("mygooglemap", y.base, {         initializer: function () {             y.on('gmaps:ready', this.render, this);             if (!isused) {                 isused = true;                 y.use("google-maps-api");             }         },         render: function () {             // safe reference global "google"             var google = y.config.global.google;             var id = this.get('node').get('id');             var map = new google.maps.map(id, {                 // ...             });             // etc         }     }, {         attrs: {             node: {                 getter: y.one             }         }     });  }, "1.0.0", {     "requires": [         "base-build",         "node-base"     ] }); 

to sum up: yui.add() necessary when writing modules depend on yui3 sandboxed resources. loading external code, long synchronous, simple employing fullpath config property. asynchronous external loading bit hairier, still possible.


Comments

Popular posts from this blog

plot - Remove Objects from Legend When You Have Also Used Fit, Matlab -

java - Why does my date parsing return a weird date? -

Need help in packaging app using TideSDK on Windows -