preload работает на уровне приложения, а не на уровне модуля. На то он и preload.
Не совсем так. Приложение является main модулем, все модули которые определяются в конфигурации приложения являются nested по отношению к нему. Preload работает на уровне модуля, но только с теми компонентами, которые определены в конфигурации этого модуля. Что логично.
Так вот, когда я пытаюсь сделать preload компонента bootstrap – он не работает, потому что preload модуля проверяет наличие конфигурации компонента в текущем модуле, и если конфига нет – пропускает его.
И правильно делает что не работает. Например:
Код: Выделить всё
// modules
'modules'=>array(
'test'=>array(
'preload'=>array('testGlobal'),
),
),
// application components
'components'=>array(
'testGlobal'=>array(
'class'=>'TestGlobalApplicationComponent',
),
Это не будет работать, т.к. в модуле test производится попытка preload компонента родительского модуля (приложения).
а при конфигурации внутри 'components' непосредственно модуля – такой способ не работает.
Это неправда. Следующий пример:
Код: Выделить всё
// modules
'modules'=>array(
'test'=>array(
'preload'=>array('testLocal'),
'components'=>array(
'testLocal'=>array(
'class'=>'TestLocalApplicationComponent',
),
),
),
),
Все отлично работает. Теперь следующий пример:
Код: Выделить всё
// modules
'modules'=>array(
'test'=>array(
'preload'=>array('testShared'),
'components'=>array(
'testShared'=>array(
'class'=>'TestSharedApplicationComponent',
'prop'=>'Test module shared component',
),
),
),
),
// application components
'components'=>array(
'testShared'=>array(
'class'=>'TestSharedApplicationComponent',
'prop'=>'Application shared component',
),
Preload отлично работает. Оба компонента доступны следующими способами:
Код: Выделить всё
$this->module->testShared; // в контроллерах и видах main модуля (приложение) возвращает компонент testShared;
$this->module->testShared; // в контроллерах и видах test модуля (nested по отношению к main модулю) возвращает компонент testShared;
Yii::app()->testShared; // откуда угодно вернет компонент testShared main модуля (приложение);
Yii::app()->getModule('test')->testShared //откуда угодно вернет компонент testShared test модуля;
Думаю, что вооружившись полученными знаниями вы элегантно решите проблему с bootstrap.
Любой компонент привязанный к модулю будет глобальным getComponent опять же от app().
Это не так. Если взять в расчет конфигурацию плана:
Код: Выделить всё
// modules
'modules'=>array(
'test'=>array(
'preload'=>array('testLocal'),
'components'=>array(
'testLocal'=>array(
'class'=>'TestLocalApplicationComponent',
),
),
),
),
то
вызовет ошибку. Как и должно быть. Таким образом нет никаких несостыковок.
Таким образом резюмируем:
Я не могу конфигурировать компонент в модуле, потому что используется Yii::app()->bootstrap.
Можете.
Я не могу сделать preload компонентов не сконфигурированных для модуля
Не можете и замечательно, учитывая, что preload работает на уровне модуля, но только с теми компонентами, которые определены в конфигурации этого модуля.
Мне приходится использовать злое шаманство в виде Yii::app()->getComponent("bootstrap"); в init модуля.
Вариант не со злым шаманством я привел.
Возможно стоит при пооиске конфигурации компонента мержить его конфиг из модуля с глобальным?
Ни в коем случае. К чему такие неожиданные побочные эффекты? В 99% случаев это будет вредным эффектом, с которым ещё и придется бороться.
Возможно стоит сделать допустимым вызов компонентов текущего модуля через Yii::app()->%componentname%
Таким вызовом можно обратиться только к компонентам main модуля (приложение). Что касется возможности вызова компонентов текущего модуля, то делать её не нужно, т.к. они никуда не исчезала и существует практически с версии 1.0.0 фреймворка:
Код: Выделить всё
$this->module->[component_name]; // в контексте контроллера или вида и т.д.