【问题标题】:yii. Accessing a function from a modules controller乙。从模块控制器访问函数
【发布时间】:2012-03-06 18:55:44
【问题描述】:

我的应用中有一个模块,在其默认控制器下,它有一个名为 renderPageLinks 的函数,它返回一个数组供小部件使用。

小部件genMenu 是从/themes/jui/views/layouts/main.php 调用的(它会生成一个菜单)我需要将renderPageLinks 中的数据作为值传递给小部件:

$this->widget('pageLinkGen', array('pages' => renderPageLinks()));

问题是 Yii 找不到函数 renderPage Links。

我尝试了以下不同的组合来使用..

$this->widget('pageLinkGen', array('pages' => 'application.module.QuickDial.default.renderPageLinks()'));

有什么建议吗?

附言我尝试将renderPageLinks() 移动到控制器pageLinkGen,但Yii 找不到renderPageLinks() 中使用的模型。

【问题讨论】:

  • 根据另一个网站的建议,我尝试了$this->widget('pageLinkGen', array('pages' => Yii::app()->getModule('QuickDial')->renderPageLinks()));,但没有任何结果。我收到以下错误:QuickDialModule 及其行为没有名为“renderPageLinks”的方法或闭包。
  • 要使该建议起作用,您必须在适当的位置声明该函数,请参阅我的回答,我已经解释了我能想到的三种方法。其中两个您已经探索过,但不正确。

标签: php yii yii-components


【解决方案1】:

假设您要查询的模型在您的模块中,有 3 种解决方法。

一个

您可以在 QuickDialModule.php 文件中定义您的 renderPageLinks() 函数,即在 QuickDialModule 类中。然后你可以这样使用它:

Yii::app()->getModule('QuickDial')->renderPageLinks();

您必须在 QuickDialModule 类中编写此函数:

Class QuickDialModule extends CWebModule{
   public function init(){
     // ... code ...
   }
   // ... code ... other functions

   public function renderPageLinks(){
       // ... do whatever you were doing inside the function ...
   }
}

编辑
只有当应用程序接收到用户的 url 请求时,yii 才会实例化控制器。

两个

通过声明您的函数static,您还有另一个解决方法。但是,您必须将 具有该函数的类的 php 文件 导入到 main.php config 文件中的 yii 自动加载数组中。因此,将您的 defaultcontroller renderPageLinks() 函数更改为静态:

public static function renderPageLinks(){
   // do whatever you were doing
}

通过修改protected/config/文件夹中的主配置main.php自动加载控制器:

// autoloading model and component classes
'import'=>array(
    'application.models.*',
    'application.components.*',
    'application.modules.quickdial.controllers.*' // this line is added
),

然后直接调用你的静态函数:

$this->widget('pageLinkGen', array('pages' => DefaultController::renderPageLinks()));

当然,要让这个静态方法起作用,你必须只有一个带有控制器 DefaultController 的模块,或者你不能导入其他模块的控制器,否则可能会出现名称冲突。

三个

如果你将函数移动到主模块中的控制器中(即你提到的 pageLinkGen 控制器),那么你必须将你需要的模型导入到主模块的配置 main.php 中(以便 yii 可以找到它),自动加载导入数组添加:

  // autoloading model and component classes
'import'=>array(
    'application.models.*',
    'application.components.*',
    'application.modules.quickdial.models.*' // this line is added
),

以便您的控制器可以找到模型。

【讨论】:

  • 如果您需要任何说明,请告诉我
  • 感谢@bool.dev 的帮助。问题是模型和函数都在同一个模块中,但它们试图在该模型之外被布局调用。至少我认为这是问题所在。我将模型移至/protected/model 并在/protected/components 中创建了一个portlet
  • 不,这应该不是问题,您以错误的方式调用函数,并且函数不在正确的位置。我在布局中对其进行了测试,并且可以正常工作。无论如何,如果您做了其他适合您的事情,那就可以了。但是对于当前形式的问题,我的回答应该有效,恕我直言。模型和函数可以在同一个模块中,看看我如何在答案中导入模型/控制器以允许类的可见性。
【解决方案2】:

如果控制器具有renderPageLinks 函数,并假设$this 是对正确控制器的引用,请尝试通过直接引用控制器来调用该函数:

$this->widget('pageLinkGen', array('pages' => $this->renderPageLinks()));

据我所知 PHP 不支持隐式$this

【讨论】:

  • 感谢您的建议,但这不起作用。问题是我调用小部件的视图在 /theme/bootstrap/layouts/main.php 中,控制器在 protected/modules/QuickDial/controllers/.. 我认为解决方案是我需要使用 portlet .
【解决方案3】:

bool.dev 的建议很棒,但在我的例子中仍然不起作用,我相信这是由于我的组织混乱。我首先将模型移动到/protected/models/,然后创建了一个包含页面渲染和调用的CPortlet 对象。我基于在blog demonstration 中找到的文档。在这个实例中,我没有从控制器中拆分视图,因为目前它只调用 Bootstrap BootNavbar 小部件。未来的主题可能会使用单独的视图页面。

再次感谢您的所有帮助。

【讨论】:

    【解决方案4】:

    我认为你应该先调用 YourModule::renderPageLinks() 方法,然后传递返回的结果:

    $pages = YourModule::renderPageLinks();
    $this->widget('pageLinkGen', array('pages' => $pages));
    

    【讨论】:

      猜你喜欢
      • 2011-07-11
      • 2012-02-17
      • 2012-01-18
      • 1970-01-01
      • 1970-01-01
      • 2010-11-04
      • 2010-11-03
      • 2015-08-03
      • 2017-02-06
      相关资源
      最近更新 更多