Я пытаюсь добавить 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
часть?
в активном модуле 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);
Однако мне нужно установить некоторые переменные динамически.
Вы не должны этого делать. Пакеты активов считаются простыми объектами для хранения (статических) путей и настроек активов — если вы начнете добавлять некоторую логику в эти классы, в некоторых случаях она начнет ломаться (например, объединение и сжатие активов).
Если у вас действительно есть несколько сценариев, вы должны создать несколько пакетов ресурсов и зарегистрировать правильный. Вы можете создать некоторый помощник, чтобы упростить это:
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()
непосредственно.
После целого дня исследований и проверки зависимостей я пришел к довольно простому решению проблемы. Оба ответа выше верны — поэтому я проголосовал за них, но они не полностью соответствовали моим конкретным потребностям.
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];
}
}
Если вы хотите разместить его внизу всего файла jJS, вам нужно написать код в виде файла, например.
После загрузки jQuery файл index.js загружается
$this->registerJsFile(Yii::$app->homeUrl.'path/of/your/index.js', ['depends' => 'yii\web\JqueryAsset']);