2

我正在使用 Behavior 向几个控制器添加操作,过度简化的行为定义为

public class GreetBehavior extends Behavior {
    public function sayHello() {
        return "Hello"
    }

    public function actionGreet() {
        return "Hello";
    }
}

该行为已成功附加。从控制器(fi Person)方法中,我可以sayHello使用$this->sayHello();. 但是,如果我从地址栏中调用它,则无法识别 actionGreet ...index.php?r=person/greet:。它给出了无法解决的消息。是否可以将动作添加到具有行为的控制器?如果是这样,你能告诉我该怎么做/我做错了什么。如果没有,你知道替代方案吗?

4

4 回答 4

3

在 Yii2 中,有两种方法可以给控制器添加动作;独立和内联。您正在尝试添加内联操作 - 这意味着它被声明为控制器类上带有“操作”前缀的方法。

加载动作的另一种方式是作为“独立”文件,在控制器的“动作”方法中定义。这将返回对其他地方存在的操作类的引用数组。


如果您查看yii\base\Controller 上的 createAction 方法(当您的应用程序运行时加载该操作),您会看到它首先查看其操作数组(独立的),如果找不到它,它会查看它自己的方法(在格式化名称并添加“操作”前缀之后 - 参见第 224-225 行)。

您遇到的问题是,当基本控制器查找内联方法时,它使用 php 的 method_exists 函数,这完全看不到 yii2 的行为功能。

我不知道为什么它不使用基本控制器上的“hasMethod”方法,它会知道行为方法。我只是在这个细节级别上查看 Yii2,所以可能有一个我不知道的原因。


所以你的问题的答案是 Yii2 目前的编码方式你不能对控制器的行为进行内联操作 - 因为当 Yii2 来寻找它时它不会被看到。

解决方案是切换到独立操作,您可以在此指南页面上阅读。

于 2016-08-01T11:16:19.927 回答
0

你不能这样做,因为动作必须从一个Controller类扩展,所以行为类中的方法不能被控制器动作替换。

您可以通过创建基本控制器并更改其他控制器以从该控制器扩展来实现此目标。如下所示:

use yii\web\Controller;
class BaseCont extends Controller{
    public function actionGreat(){
        return "Hello";
    }
}

然后通过创建一个控制器来扩展它,如下所示:

class MyController extends BaseCont{
    //rest of code
}

greatAction除了在MyController.

于 2014-11-03T10:42:41.830 回答
0

使用控制器::actions()

public function actions() {
    return [
        'ajaxsearch' => [
            'class'=>'app\components\searchlinewidget\AjaxSearchAction',
            'searchClass'=>PublisherSearch::className()
        ]
    ];
}
于 2015-06-07T17:27:03.677 回答
-1

您可以使用 Actions 类定义添加操作。请参阅此处的第 3 项http://www.yiiframework.com/doc/guide/1.1/en/basics.controller

您的问题正在这里讨论:

不,这是不可能的,因为CController::createAction()检查“actionExample”是否是给定控制器的有效方法。行为方法在控制器中不是真正的方法,因为它们是通过 magic 调用的__get()

现在,作为解决方法,我猜你可以覆盖CController::createAction()CController::missingAction()以某种方式让它工作。

http://www.yiiframework.com/forum/index.php/topic/10652-actions-by-behavioring/

于 2014-11-03T13:55:36.913 回答