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/

Другие вопросы по тегам