After inspecting YUI Loader, i have some more ideas.
YUI Loader adds a <script> tag for each script, that needs to be loaded. This is a good thing, as the browser then will cache the loaded script. I've also thought about dependencies. But i tried to keep it as simple as possible. So how about this:
-
The loader could become part of jquery.yii.js and provide 2 methods: jquery.yii.load() and jquery.yii.register(). So when using the loader, jquery must already be loaded.
-
jquery.yii.load(urls, success) accepts two parameters: a literal objects with url/modulename pairs, and a callback function that’s called after all scripts loaded completely.
jquery.yii.load(
{
'/assets/1c9535/jquery.yiitab.js' : 'yiitab' // value could also be an array
},
function () {
/* init stuff, that depends on the loaded script /*
}
);
- Every loaded js script needs an additional line in the end to register itself with the loader and let him know, that it's loaded completely. E.g. in jquery.yiitab.js this line would get added:
jquery.yii.register('yiitab');
An example page flow could then look like this:
1. Complete Page loads, with e.g. this content
<head>
...
<script type="text/javascript" src="/assets/d652f40f/jquery.js"></script>
<script type="text/javascript" src="/assets/1c978867/jquery.yii.js"></script>
...
</head>
<body>
....
<!-- loader call, generated by some view that uses a CTabView: -->
<script type="text/javascript">
/*<![CDATA[*/
jquery(function(){
jquery.yii.load(
{'/assets/abcdefg/jquery.yiitab.js':'yiitab'},
function() { /* init tabview */}
);
});
/*]]>*/
</script>
When the page is loaded, jquery.yiitab.js will be loaded and the tabview will get initalized afterwards. It's not required to use the loader here. The according script tag could also be added after the jquery.yii.js tag in the header.
2. An AJAX call is made to update parts of the page.
The loaded view contains another CTabView and a CStarRating. At the end of the HTML response, this script is added:
<!-- loader call, generated by some view that uses a CStarRating: -->
<script type="text/javascript">
/*<![CDATA[*/
jquery(function(){
jquery.yii.load(
{'/assets/abcdefg/jquery.yiitab.js':'yiitab'},
function() { /* init tabview */}
);
jquery.yii.load(
{
'/assets/abcdefg/jquery.dimensions.js' : 'dimensions',
'/assets/abcdefg/jquery.metadata.js' : 'metadata'
},
function() { /* init CStarRating */}
);
});
/*]]>*/
</script>
The loader would find yiitab already loaded and immediately call the success callback. The required js for CStarRating would be loaded, and it's init also called afterwards.
To ease generation of these loader block, a util function could be used. It could also allow adding custom js files. So if someone wants to use a minified js file, it would generate something like this:
<script type="text/javascript">
/*<![CDATA[*/
jquery(function(){
jquery.yii.load(
{'/assets/abcdefg/my-custom-min.js': ['yiitab','bgiframe', 'dimension'] },
function() { /* init stuff */}
);
});
/*]]>*/
</script>
The min file must register the according modules:
yii.register( ['yiitab','bgiframe','dimension'] );
What do you guys think? Maybe we also need a type for the urls, to be able to include CSS.