Я использую Поведение, чтобы добавить действие к нескольким контроллерам, упрощенное поведение определяется как
public class GreetBehavior extends Behavior {
public function sayHello() {
return "Hello"}
public function actionGreet() {
return "Hello";
}
}
Поведение прикреплено успешно. Из метода Controller (например, Person) я могу получить доступ sayHello
с $this->sayHello();
,
Однако actionGreet не распознается, если я вызываю его из адресной строки: ...index.php?r=person/greet
, Это дает сообщение, что это не может быть решено. Можно ли добавить действия к контроллеру с поведением в любом случае? Если да, можете ли вы дать мне подсказку, что делать / что я делаю неправильно. Если нет, знаете ли вы альтернативу?
В Yii2 есть два способа добавить действия к контроллеру; автономный и встроенный. Вы пытаетесь добавить встроенное действие — это означает, что оно объявлено как метод в классе контроллера с префиксом ‘action’.
Другой способ загрузки действий — это «автономные» файлы, которые определены в методе «действий» контроллера. Это возвращает массив ссылок на классы действий, которые существуют в другом месте.
Если вы посмотрите на метод createAction на yii \ base \ Controller (который загружает действие при запуске приложения) вы можете увидеть, что оно сначала просматривает свой массив действий (автономные), а если не может его найти, то просматривает свои собственные методы (после форматирования имени и добавления ‘действия префикс — см. строки 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/