Yii 2.0 & Ajax/renderPartial conflict
#1
Posted 14 October 2011 - 01:08 AM
Just wondering what the story is for Yii 2.0 and the Ajax & renderPartial conflict. Is this going to be addressed in the next major release? Is it even addressable? I think it throws many people for a loop and it's one example that contributes to Yii's perceived steep(ish) learning curve.
Maybe this would be a good place to start a brain storm for solutions. Any ideas?
Cheers,
Matt
#2
Posted 14 October 2011 - 05:44 AM
if and only if loaded via ajax and multiple times!!!

Test Yii:
Yii Framework Demos
Wiki:
Common Yii Questions
Tutorials:
Demo Blog Search with Zend_Lucene
Fundamentals:
Yii "registry" | Understanding the layout->view randering flow
Etc:
Shrink Yii | Caching config/main.php | CPhpAuthManager - how it works, and when to use it
Extensions:
Theme Picker | Language Picker (i18n)
#3
Posted 14 October 2011 - 05:56 AM
The problem arrise because some JS files (but even JS code snippets) are re-included with the ajax call... in the first place jquery.js... but even other JS files...
Main problem is - how can YII know what files has been already included from the previous call?
One solution would be to keep included files in sessions and every time a JS file (and snippet) needs to be included to check the session for the name of the file (or snippet)... I'm not sure on how would that affect the performance as memory consumption and as checking every JS file that is included...
The other solution that one forum user made is to have a jQuery ajax event handler and to check script names when they are included... and to deny those that already are... problem with this solution is that while the files will not be included they are still downloaded to the client... and works only for files not for Yii/JS snippets
All this is not a problem if you "understand" how ajax calls works and what they do (need to do)... as the solution is by including all needed JS files and snipets in the main view... and on renderpartials to only return clean HTML or json...
Sometime this is not possible, for example when using CGridView in the renderPartial... in those cases again all the JS files needs to be included by the main view file and then scriptMap can be used to prevent loading of those files on ajax calls...
I'm open for some "creative" ideas on how to solve this.
#4
Posted 14 October 2011 - 08:20 AM
It's a little bit messy that this list then needs to be sent with every ajax request (only ones that would actually return html) which then get used with the script map to filter them out.
This allows the first call to include the scripts and run them and all subsequent calls ignore the loaded scripts.
One issue I did have with this though is files with the same name will ignored so doesn't help where some widgets have the same name for css files.
#5
Posted 14 October 2011 - 04:27 PM
My solution (and I rewrote my yii .js scripts...) is to attach to body attribute...
so instead of attach event again and again for example, they attached only if body not have some tag...

Test Yii:
Yii Framework Demos
Wiki:
Common Yii Questions
Tutorials:
Demo Blog Search with Zend_Lucene
Fundamentals:
Yii "registry" | Understanding the layout->view randering flow
Etc:
Shrink Yii | Caching config/main.php | CPhpAuthManager - how it works, and when to use it
Extensions:
Theme Picker | Language Picker (i18n)
#6
Posted 14 October 2011 - 06:03 PM
Quote
I used to use the solution you said, all js/css files in the first request, then a couple months ago I adapted it to a more complex solution.
Yii2 should have a response object. It should also contain a js script to handle ajax responses.
Ajax requests send the response in json, sending the list of js/css files and scripts/styles ( registered in clientScript ) to be include and executed, along with the response body , something like this:
{ content:'some html or json here', scriptFiles:['list of js files'] cssFiles:['list of css files'], styles:{ styleID:'some css style here' }, scripts:{ scriptID:'some javascript', otherScript:'other javascript to be executed' } }
The js object that handles ajax requests is a singleton that will contain all js/css files and styles/scripts already executed.
It will then include the new js and css files, after that it will execute the styles and scripts.
clientScript should be modified to work with the response class.
Then in my js file what I do is to check the response type, if json it will be handled by the response object.
Extensions:
translate modue - module to handle translations
multiActiveRecord - db selection in models
redisCache - redis cache component
mpCpanel - interact with cpanel api
mUploadify - use uploadify uploader in your application
Gustavo Salomé Silva
#7
Posted 18 March 2012 - 11:00 PM
If the way goes through the first question, the answer to this problem is: JUST COPY THAT, by the other hand, if the way goes thought the second question, the answer is: THERE IS NO RIGHT SOLUTION to this problem, because it didn't get solved by dozens of historical and well known frameworks in the past.
I hope I could help on this big issue Im suffering ourselfs in our platform :-D
regards,
alex
P.S: In my opinion this question (problem) should never answer (resolved) in Yii 2.0 only, because this is a big issue to solve for yii 1.1.x users also, to not force us to upgrade a major version (with the stability and backward compatibility issues it could involve for productions enviroments).
#8
Posted 21 February 2013 - 08:35 PM
Most of my work is backend stuff so I can afford a larger initial download with the advantage of less trips to the server for subsequent js files. It works well for me, but maybe not what you wanted to hear?
But I agree, it's not a good situation and needs some thought.
#9
Posted 22 February 2013 - 12:18 PM
if(isset($_GET['ajax']))) { Yii::app()->clientScript->scriptMap['jquery.js'] = false; Yii::app()->clientScript->scriptMap['jquery.min.js'] = false; $this->renderPartial('_form',array('model'=>$model), false, true); }
#10
Posted 26 February 2013 - 10:43 AM
yJeroen, on 22 February 2013 - 12:18 PM, said:
if(isset($_GET['ajax']))) { Yii::app()->clientScript->scriptMap['jquery.js'] = false; Yii::app()->clientScript->scriptMap['jquery.min.js'] = false; $this->renderPartial('_form',array('model'=>$model), false, true); }
I use this approach with even stronger limitation:
if (Yii::app()->request->getIsAjaxRequest()) { Yii::app()->clientScript->scriptMap['*.js'] = false; Yii::app()->clientScript->scriptMap['*.css'] = false; }
#11
Posted 23 April 2013 - 10:42 AM
#12
Posted 29 May 2013 - 02:59 PM

#13
Posted 03 June 2013 - 04:02 AM
But then I found a simple answer to this problem: loading js/css files with ajax request is just wrong.
Don't we want to make our ajax calls fast and tiny? Or we want to blindly load a bunch of js/css files when doing ajax call?
So in my opinion the best and easiest solution is to include all necessary scripts into the page and do block all scripts (see my post above) during ajax request.
And including all related scripts into the page will be simple in Yii2 using client script bundles feature.
#14
Posted 03 June 2013 - 11:57 PM
Yii::app()->clientScript->scriptMap['jquery.js'] = false; Yii::app()->clientScript->scriptMap['jquery.min.js'] = false; $this->renderPartial('_form',array('model'=>$model), false, true);
Wiwo inc.
| Mobile: 919995504508
#15
Posted 04 June 2013 - 02:57 AM
Rajith R, on 03 June 2013 - 11:57 PM, said:
Yii::app()->clientScript->scriptMap['jquery.js'] = false; Yii::app()->clientScript->scriptMap['jquery.min.js'] = false; $this->renderPartial('_form',array('model'=>$model), false, true);
Isn't this loading scripts via ajax if you have $processOutput=true?
#16
Posted 03 September 2013 - 06:22 PM
I could not get it working, so I ended up putting it in an iframe inside CJuiTabs.
Maybe ugly, but effective for beginners like me.
CGridView in iframe in CJuiTabs
#17
Posted 05 September 2013 - 06:32 AM
and suddenly these built in (mostly jQueryUI) components are not usable with ajax
#18
Posted 02 June 2015 - 08:44 AM
What is the current solution?