Management of script downloads (e.g. "Ajax script downloads")

There doesn’t seem to be any discussion about how Yii 2.0 will manage scripts. Everybody knows the current issue of duplicate script downloads when using AJAX, so I was wondering if someone came up with an approach to make this a bit easier. There’s an extension called NLSClientScript (http://www.yiiframework.com/extension/nlsclientscript) extending CClientScript which basically reads the script url to check wheter a script has been downloaded already. I personally never used it but it seems like an interesting (and easy to implement) approach. What do you guys think?

Although it’s the quick and easy way, I really think using processOutput() on ajax requests is a bad idea full stop. It’s almost always better to implement that functionality in a separate JS module, it’ll be a lot easier to test. One of the most annoying things that always happens is you end up with 2 distinct elements on the same page with the same id, e.g. yw1 and now all the scripts are broken anyway.

Slightly related: I really think it would be good if Yii had a rails style assets pipeline, everyone is rolling their own implementation at the moment to minify and concatenate javascript and CSS. 2.0 should provide a solution by default. This would also make this particular problem go away because on AJAX requests you could just assume that all script files have already been registered and only the inline scripts need to be rendered.

That seems to be a really interesting concept. For those not familiar with Rails’ asset pipeline: Rails Docs: Asset Pipeline

I got around this issue by overriding the "clean" function in jQuery.

This allowed me to catch every insert of a JS or CSS file and store them in an array so they can be ignored if called again.

Hi all!

I use NLSClientScript in my projects and sometimes it’s looks very useful.

For example:

I have page with several tabs, each tab should contain some widget. First tab is visible on page load, others can be activated by click and should load content via ajax. But with current Yii 1.1 I need to put contents of all tabs on initial page loading (inspite of fact that user sees only first tab and maybe never click on other). It’s extra job for both server and client sides.

My suggestion for Yii2 is to extend CWidget with method to render assets only (something like renderAssets()). In this case all required js/css will be loaded without widget initialization itself.

You mean you are missing a renderPartial for widgets like the one the controllers provide to process outputs? I thought about this problem once because I wanted to use


$this->renderPartial('widgetview',array('data'=>$data),false,true); 

within a widget, which isn’t possible right now (a workaround would be to use $this->controller->renderPartial I think) but at the end of the day the problem is that as long as we are using a pure backend language to create the fancypants js/ajax stuff on the client side it will always be a tradeoff.

I am using this structure right now and I got used to it:


- js

    - controllers

       - post

           * create.js

           * view.js

       - comment

           * create.js

           * ....

- protected

    - views

        - post

            * create.php



So if I render post/create I also register the script under js/controllers/post/create.js. It is more work, but at least you have full control over your client side code. I never use any ajaxXXX methods provided by Yii (except CActiveForm)

@Haensel:

not exactly… renderPartial within widget may be usefull, but I mean controller’s renderPartial() with process output. I use this structure




$this->renderPartial('widgetview',array('data'=>$data),false,true); 



but it requires NLSClientScript. Otherwise as already mentioned js will be processed twice.

I mean, for example, for CGridView I need yiigridview.js that located in some directory inside assets. I would like to call something like:




CGridView::registerAssets();



to add all required assets on page loading.

Afterwards I can render grid itself at any time via ajax on user request.