Большой вопрос, на мой взгляд, и я думаю, что он возникает довольно часто.Я на самом деле имел дело с подобной проблемой, когда я хотел, чтобы какой-то сбор данных или функциональность в масштабе всего сайта были добавлены в компонент.
Первое, что нужно иметь в виду:
Книга является руководством.
Эти «правила» не являются правилами.Если есть хорошая причина для нарушения правила, и вы понимаете , почему нарушается правило, тогда сломайте эту чертову вещь!Сам пирог нарушает это правило довольно часто.
Основные компоненты, которые требуют / используют модели:
- Acl
- Auth
- Сеансы (довольно положительно, вы можете сохранить данные сеанса в модели)
Итак, очевидно, есть случаи, когда вам нужно использовать модель внутри компонента.Как ты это делаешь?
Ну, есть пара разных способов.Чем я закончил?Примерно так:
<?php
ModelLoadingComponent extends Object {
public function startup($controller) {
$controller->loadModel('Model');
$this->Model = $controller->Model;
}
}
?>
Вот и все!Теперь ваш компонент настроен на использование $this->Model
... так же, как в контроллере.
Редактировать:
Извините, чтобы уточнить: нет, вы нене нужно настраивать новый компонент для загрузки моделей.Я показываю пример того, как вы можете загрузить компонент в любой модели.Функция startup
, которую я использовал, является специфичным для компонента обратным вызовом, их множество http://book.cakephp.org/view/998/MVC-Class-Access-Within-Components. Эти методы обратного вызова делают компоненты намного более удобными для работы.Я настоятельно рекомендую просмотреть эту часть руководства по компонентам, если ничего другого.
Если вы работали внутри объекта AppController
, вы могли бы вызвать $this->loadModel()
, но мы не работаем с AppController
!Мы работаем с компонентом, действительно Object
.Там нет Object::loadModel()
, поэтому мы должны придумать другой способ получить эту модель.Именно здесь $controller
вступает в игру в нашем startup
обратном вызове.
Когда Cake вызывает метод startup
, он передает объект $controller
, с которым он работает, в этой диспетчеризации в качестве первого параметра.Благодаря этому мы можем получить доступ к методам контроллера ... как loadModel()
.
Почему мы делаем это таким образом?
Ну, мы могли бы использовать ClassRegistry::init('Model')
в каждом из нашихКомпонентные методы, которые должны использовать модель.Если у вас есть 10 методов в вашем компоненте, и только один из них использует модель, это может сработать.Однако что, если у вас есть 10 методов в вашем компоненте, и все 10 из них используют модель?Ну, вы бы звонили ClassRegistry :: init ('Model') 10 раз!Это большая нагрузка, когда вам действительно нужен только один модельный объект.С помощью этого метода компонент создает один объект модели.Тот, который мы создаем в startup
.
Надеюсь, это прояснит ваши вопросы и даст некоторое представление о том, почему я использую этот метод для моделей в компонентах.
Редактировать: Добавлено уточнение кода после того, как япровел некоторые эксперименты.