【问题标题】:Yii2 - Intercept Render ActionYii2 - 拦截渲染动作
【发布时间】:2018-05-30 10:03:55
【问题描述】:

我正在编写 Yii2 基本应用程序。有时我必须在将控制器的操作作为部分访问时渲染视图,有时我必须使用布局来渲染它们。这是基于请求中的 GET 参数,因此我在操作中的代码如下所示:

public function actionIndex() {
    $isApi = Yii::$app->request->get('api');

    $dataProvider = new ActiveDataProvider([
        'query' => Participant::find(),
    ]);

    if ($isApi) {
        return json_encode($this->renderPartial('index', [
                    'dataProvider' => $dataProvider,
        ]));
    } else {
        return $this->render('index', [
                    'dataProvider' => $dataProvider,
        ]);
    }
}

我对每个控制器中的每个操作都有完全相同的逻辑。我必须首先检查GETapi 变量的请求,然后根据该请求调用renderrenderPartial 函数。

有没有办法截取每个动作中的渲染部分并编写此代码以在全局范围内为每个动作工作,而不是到处复制粘贴?

【问题讨论】:

    标签: yii2 rendering


    【解决方案1】:

    您可以为此编写方法:

    public function actionIndex() {
        $dataProvider = new ActiveDataProvider([
            'query' => Participant::find(),
        ]);
    
        return $this->renderForApi('index', [
            'dataProvider' => $dataProvider,
        ]);
    }
    
    protected function renderForApi($view, $params = []) {
        $isApi = Yii::$app->request->get('api');
        if ($isApi) {
            return $this->asJson($this->renderPartial($view, $params));
        }
    
        return $this->render($view, $params);
    }
    

    您可以将renderForApi() 方法放入应用程序的父控制器中,也可以将其放入特征中并在每个控制器中使用。

    【讨论】:

    • 好提示。还想到改写渲染方法,但您的解决方案应该可以正常工作!
    • 重写render()方法可能会带来意想不到的副作用,我不建议这样做。
    • 足够合理。使用上面的解决方案,它可以工作。谢谢!