我想知道是否有一种理想的方法可以在每个视图文件中运行相同的代码。
不是必须修改所有控制器和所有操作并添加代码片段,是否有办法让控制器和操作始终被任何视图调用(而不是部分视图)?
我在所有视图中需要的是获取当前登录用户并获取其他相关表中数据的代码。
以下是其中一个观点的行动方法之一
public function actionIndex()
{
// the following line should be included for every single view
$user_profile = YumUser::model()->findByPk(Yii::app()->user->id)->profile;
$this->layout = 'column2';
$this->render('index', array('user_profile' => $user_profile));
}
答案 0 :(得分:3)
是的,可以使用布局和基本控制器。
如果你来自Yii代码生成器,Controller
文件夹中应该有一个components
类。
如果您的控制器ExampleController extends Controller
代替CController
,
在Controller
中,您可以指定:
public function getUserProfile() {
return YumUser::model()->findByPk(Yii::app()->user->id)->profile;
}
在你的布局文件中:
<?php echo CHtml::encode($this->getUserProfile()); ?>
因为$this
引用了控制器,并且控制器继承了名为$user_profile
的属性。
但是,您应该在登录会话时分配profile
和其他不会因setState
而变化的内容。这样你可以做类似的事情:
<p class="nav navbar-text">Welcome, <i><?php echo Yii::app()->User->name; ?></i></p>
在MySQLUserIdentity中设置状态的示例(由我完成)。
class MySqlUserIdentity extends CUserIdentity
{
private $_id;
public function authenticate()
{
$user = User::model()->findByAttributes( array( 'username' => $this->username ) );
if( $user === null )
$this->errorCode = self::ERROR_USERNAME_INVALID;
else if( $user->password !== md5( $this->password ) )
$this->errorCode = self::ERROR_PASSWORD_INVALID;
else
{
$this->_id = $user->id;
$this->setState( 'username', $user->username );
$this->setState( 'name', $user->name );
$this->setState( 'surname', $user->surname );
$this->setState( 'email', $user->email );
$this->errorCode = self::ERROR_NONE;
}
return !$this->errorCode;
}
public function getId()
{
return $this->_id;
}
}
答案 1 :(得分:3)
如评论中所述,将重复逻辑放在控制器中并不好。记住MVC逻辑 - 厚模型,明智视图和瘦控制器。为了显示登录的用户数据,我建议创建一个小部件。您可以将该小部件放置在布局中或任何视图中。
最简单的是
class MyWidget extends CWidget
{
private $userData = null;
public function init()
{
$this->userData = YumUser::model()->findByPk(Yii::app()->user->id)->profile;
// Do any init things here
}
public function run()
{
return $this->render('viewName', array('user_profile' => $userData));
}
}
然后在任何视图(或实际上也是视图的布局)中你可以使用它:
$this->widget('path.to.widget.MyWidget');
有关详细信息,请参阅docs on Yii widgets