Yii2在所有js文件的末尾注册资产文件(js)

时间:2018-10-18 11:50:15

标签: php jquery yii2 assetbundle

我试图通过页面末尾的js-file向我的视图中添加一个AssetBundles

将静态方法与MyAssetBundle::register($this->view)一起使用时,我可以将jsOptions'position' => \yii\web\View::POS_END一起使用,这应该可以正常工作。

但是,我需要动态设置一些变量。因此,我尝试使用MyAssetBundle类和registerAssetFiles类而不是register的实例。

我的方法:

$myAsset= new MyAssetBundle();
//...do some stuff with the variables (+ load different css/js files based on the variables)
$myAsset->registerAssetFiles($this->view);

基本上仍然可以使用,问题是js-files位于所有js-files的顶部,因此如果我在jQuery中使用js-file,则会得到Uncaught ReferenceError: jQuery is not defined,因为jQuery文件包含在文件之后。

我对Yii还是很陌生-有没有一种方法可以在js部分的末尾包含我的文件?

4 个答案:

答案 0 :(得分:3)

Yii资产模块中有5个职位

  

const POS_HEAD = 1;

     

const POS_BEGIN = 2;

     

const POS_END = 3;

     

const POS_READY = 4;

     

const POS_LOAD = 5;

如果要将文件放在整个文件的按钮中, 您可以使用

  

$ this-> view-> registerJsFile('/ path / to / js',POS_LOAD);

     

$ this-> view-> registerCssFile('/ path / to / css',POS_LOAD);

如果要将其放置在所有js文件的顶部 您可以选择合适的POS 在您的问题中,我认为这会对您有所帮助

  

$ this-> view-> registerJsFile('/ path / to / jquery',POS_BEGIN);

答案 1 :(得分:1)

  

但是,我需要动态设置一些变量。

您不应该这样做。资产束被认为是用于存储(静态)资产路径和设置的简单实体-如果您开始向这些类中添加一些逻辑,则在某些情况下它将开始中断(例如合并和压缩资产)。

如果确实有多个场景,则应创建多个资产束并注册正确的资产束。您可以创建一些帮助程序来简化此操作:

class AssetsHelper {

    public const SCENARIO_A = 'a';
    public const SCENARIO_B = 'b';

    public static function register(View $view, string $scenario) {
        switch ($scenario) {
            case static::SCENARIO_A:
                AssetBundleA::register($view);
                break;
            case static::SCENARIO_B:
                AssetBundleB::register($view);
                break;
            default:
                throw new InvalidArgumentException("Unsupported scenario: $scenario.");
        }
    }
}

在视野中:

AssetHelper::register($this, $scenario);

如果您的资产规则过于复杂和/或动态,无法为每种情况创建单独的资产捆绑类,则您应该退出使用资产捆绑,而直接使用registerCssFile()registerJsFile()

答案 2 :(得分:0)

经过一整天的研究并检查了依存关系,我找到了一个非常简单的解决方案。上面的两个答案都是正确的-因此我投票赞成,但它们并不完全符合我的特定需求。

AssetBundle类带有一个变量$depends和一个变量$jsOptions-不能单独工作。但是在检查依赖项时,我意识到$jsOptions也有一个参数depends

因此,我创建了一个构造函数,该构造函数将depends中的$jsOptions设置为我所有需要的资产,这些资产必须包含在我的文件之前。

我的解决方案:

class AjaxPanelAsset extends AssetBundle
{
   public $basePath    = '@webroot';
   public $baseUrl     = '@web';
   public $css = [

   ];
   public $js = [

   ];

   public $depends = [
    'yii\web\YiiAsset',
    'yii\bootstrap\BootstrapAsset',
    'yii\bootstrap\BootstrapPluginAsset',
   ];

   public function setCSSJSFiles($css,$js)
   {
    $this->css = array($css);        
    $this->js = array($js);
   }

   public function __construct(){
    $this->jsOptions= ['depends' => $this->depends];
   }

}

答案 3 :(得分:0)

如果要将其放置在所有jJS文件的底部,则需要在视图文件中编写代码,例如。

在jQuery加载index.js文件后

$this->registerJsFile(Yii::$app->homeUrl.'path/of/your/index.js', ['depends' => 'yii\web\JqueryAsset']);