Closed RomeroMsk closed 9 years ago
I suppose it could be better if we could have an option when using renderAjax
to specifically isolate the following:
AssetBundle::register($view)
.registerJs
, registerCss
, registerJsFile
, registerCssFile
methods. Then we could control registration of asset bundles separately and inline scripts/additional files separately in renderAjax
... in such complex view rendering process.
you can unregister assets by using ie.:
yii\web\View Object
(
[assetBundles] => Array
(
)
)
-->
unset($this->assetBundles['yii\web\JqueryAsset']);
Where? In controller and view itself assetBundles
is not filled yet. All assets will be defined and filled only inside rendering methods.
by using a ajax-layout for the renderAjax
I guess you could also try to use Events for this matter. Perhabs View::EVENT_AFTER_RENDER and then use \Yii::$app->view
@dynasource yes, your suggestion about ajax layout is working. I'm calling render
instead of renderAjax
and using special layout with such code:
<?php
unset($this->assetBundles['yii\bootstrap\BootstrapAsset']);
unset($this->assetBundles['yii\web\JqueryAsset']);
unset($this->assetBundles['yii\web\YiiAsset']);
unset($this->assetBundles['kartik\widgets\Select2Asset']);
unset($this->assetBundles['kartik\widgets\WidgetAsset']);
?>
<?php $this->beginPage() ?>
<?php $this->head() ?>
<?php $this->beginBody() ?>
<?= $content ?>
<?php $this->endBody() ?>
<?php $this->endPage() ?>
(as universal solution I can pass an array of bundles to unset from controller action). Thanks! But Kartik's idea is much better than this workaround. Let's wait for Yii devs to look on this.
Youre welcome. I do think passing data around would make the framework complex. The View component is accessible in the application which would enable one to unset assetBundles easily with ie. Events.
@RomeroMsk yes its register
- corrected it.
@dynasource if you try to access assetBundles
from controller action before rendering you'll see it's empty (because all assets will be included inside rendering method). I didn't try event (honestly, I don't know how to attach event listener to view from controller before rendering it by view name), but I think it also won't work.
Romero, I didnt say that before rendering worked. EVENT_AFTER_RENDER is the one you need. To help you out with an example. Put this anywhere in your code:
\yii\base\Event::on(\yii\web\View::className(), \yii\web\View::EVENT_AFTER_RENDER, function ($e) {
$e->sender->assetBundles = [];
});
@dynasource it's magic :) I used your example and it's working. Now I don't need special layout, I'm just attaching event listener with unsets and calling renderAjax. Thank you again, this is the way I've looking for! I leave this issue opened to see devs comments about this case.
If your ajax response has some <script src=""></script>
tags that already exist on the page Yii should stop them from being requested again.
Unfortunately it doesn't work for CSS.
true. Currently, I am using a custom implementation to prevent 'similar' scripts being included. To give you a direction:
var jsFiles = <?php echo \yii\helpers\Json::encode(($this->context->jsFiles[View::POS_END]))?>;
var jsFilesDone = $('script[src]');
$.each( jsFiles, function( url,script ) {
var matchedScripts = jsFilesDone.filter(function () {
return this.src === 'http://' + document.location.host + url;
})
if (!matchedScripts.length) jsFilesTodo.push(url);
});
Insert this code before render )) Yii::$app->assetManager->bundles = [ 'yii\bootstrap\BootstrapPluginAsset' => false, 'yii\bootstrap\BootstrapAsset' => false, 'yii\web\JqueryAsset' => false, ];
Romero, I didnt say that before rendering worked. EVENT_AFTER_RENDER is the one you need. To help you out with an example. Put this anywhere in your code:
\yii\base\Event::on(\yii\web\View::className(), \yii\web\View::EVENT_AFTER_RENDER, function ($e) { $e->sender->assetBundles = []; });
This works! Thank you!
Hello. I have this case: On
page1
there is Bootstrap Modal which content is loading via ajax frompage2
. To not include header and footer intopage2
I'm using renderAjax in page2 controller. But I need to exclude some assets which are loading automatically: for example, Bootstrap offset. I have two reasons for this:page1
) and I don't need unnecessary network requests for these CSS and JS files.page1
I'm using my own css file which overrides some Bootstrap styles. And when modal content is loaded, styles ofpage1
are overriding by bootstrap.css.So I'm looking for a way to exclude specified assets from rendering (by renderAjax, as minimum).
P.S. renderPartial is not a solution, beacuse in case of using it inline JS registered by widgets are missing.