Yii2: Как сослаться на действие, привязанное к контроллеру с поведением?
Я использую Поведение, чтобы добавить действие к нескольким контроллерам, упрощенное поведение определяется как
public class GreetBehavior extends Behavior {
public function sayHello() {
return "Hello"
}
public function actionGreet() {
return "Hello";
}
}
Поведение прикреплено успешно. Из метода Controller (Fi Person) я могу получить доступ sayHello
с $this->sayHello();
, Однако actionGreet не распознается, если я вызываю его из адресной строки: ...index.php?r=person/greet
, Это дает сообщение, что это не может быть решено. Можно ли в любом случае добавить действия к контроллеру с поведением? Если да, можете ли вы дать мне подсказку, что делать / что я делаю неправильно. Если нет, знаете ли вы альтернативу?
4 ответа
В Yii2 есть два способа добавить действия к контроллеру; автономный и встроенный. Вы пытаетесь добавить встроенное действие - это означает, что оно объявлено как метод в классе контроллера с префиксом 'action'.
Другой способ загрузки действий - это "автономные" файлы, которые определены в методе "действий" контроллера. Это возвращает массив ссылок на классы действий, которые существуют в другом месте.
Если вы посмотрите на метод createAction в yii \ base \ Controller (который загружает действие при запуске приложения), вы можете увидеть, что он сначала просматривает свой массив действий (автономные), и если он не может его найти, он просматривает свои собственные методы (после форматирования имени и добавления префикса 'action' - см. строки 224-225).
Проблема, с которой вы столкнулись, заключается в том, что когда базовый контроллер ищет встроенный метод, он использует функцию php method_exists, которая полностью закрывает функциональность поведения yii2.
Я не знаю, почему он не использует метод hasMethod на базовом контроллере, который знает о методах поведения. Я только смотрю на Yii2 на этом уровне детализации, хотя, возможно, есть причина, о которой я не знаю.
Таким образом, ответ на ваш вопрос заключается в том, что в соответствии с тем, как Yii2 в настоящее время кодируется, вы не можете встроить действие в поведение контроллера - потому что его не будет видно, когда Yii2 начнет его искать.
И решение состоит в том, чтобы перейти к автономным действиям, о которых вы можете прочитать на этой странице руководства.
Вы не можете сделать это, так как действия должны быть расширены с Controller
класс, поэтому метод в классе поведения не может быть заменен действием контроллера.
Вы можете достичь этой цели, создав базовый контроллер и изменив другие контроллеры для расширения с этого контроллера. Как ниже:
use yii\web\Controller;
class BaseCont extends Controller{
public function actionGreat(){
return "Hello";
}
}
Затем, создав контроллер, который расширяет его, как показано ниже:
class MyController extends BaseCont{
//rest of code
}
У вас будет greatAction
в дополнение к другим вашим действиям в MyController
,
Использовать Controller::actions()
public function actions() {
return [
'ajaxsearch' => [
'class'=>'app\components\searchlinewidget\AjaxSearchAction',
'searchClass'=>PublisherSearch::className()
]
];
}
Вы можете добавить действия с определением класса Actions. См. Пункт 3 здесь http://www.yiiframework.com/doc/guide/1.1/en/basics.controller
Ваши вопросы обсуждаются здесь:
Нет, это пока невозможно, потому что CController::createAction()
проверяет, является ли "actionExample" допустимым методом для данного контроллера. Методы поведения не являются реальными методами в контроллере, так как они вызываются с помощью магии __get()
,
На данный момент, как обходной путь, я думаю, вы можете переопределить CController::createAction()
или же CController::missingAction()
каким-то образом заставить его работать.
http://www.yiiframework.com/forum/index.php/topic/10652-actions-by-behavioring/