设计问题-保持对话框与主视图文件分开并访问它们



我有一个案例,在我的视图文件中有6个链接,点击它们打开CJuiDialog框。我保持所有的6个对话框代码在同一视图文件与链接,这是导致文件很大,并加载他们一起一次。理想的情况是对话框应该加载只有当使用点击链接。

那么有没有办法让我们只把链接代码放在主视图文件中而把所有的对话框放在单独的文件中并且只在用户点击链接时才加载它们

我是说

index.php ( view containing only links)
_dialog1 ( containing code for first dialog )
_dialog2 ( containing code for second dialog )
_dialog3 ( containing code for third dialog )
_dialog4 ( containing code for fourth dialog )
_dialog5 ( containing code for fifth dialog )
_dialog6 ( containing code for sixth dialog )
样例代码

//First Dialog code
     $this->beginWidget('zii.widgets.jui.CJuiDialog', array(
            'id'=>'mydialog1',
            'options'=>array(
                'title'=>'Dialog box 1',
                'autoOpen'=>false,
                'modal'=>true,      
            ),
        ));
        echo 'First dialog content here';
        $this->endWidget('zii.widgets.jui.CJuiDialog');
        echo CHtml::link('open dialog', '#', array(
            'onclick'=>'$("#mydialog1").dialog("open"); return false;',
        ));
//2nd dialog code 
$this->beginWidget('zii.widgets.jui.CJuiDialog', array(
            'id'=>'mydialog2',
            'options'=>array(
                'title'=>'Dialog box 1',
                'autoOpen'=>false,
                'modal'=>true,      
            ),
        ));
        echo 'dialog2 content here';
        $this->endWidget('zii.widgets.jui.CJuiDialog');
        echo CHtml::link('open dialog', '#', array(
            'onclick'=>'$("#mydialog2").dialog("open"); return false;',
        ));

解决方案是

//In controller
       public function actionOpenDialog1()
    {
        $data = array();
        $this->renderPartial('_dialogContent1', $data, false, true);
    }
       public function actionOpenDialog2()
    {
        $data = array();
        $this->renderPartial('_dialogContent2', $data, false, true);
    }
//In index.view
<div id="data">
</div>
<?php
echo CHtml::ajaxButton ("Open first dialog", CController::createUrl('dialogTesting/openDialog1'),array('update' => '#data'));
echo CHtml::ajaxButton ("Open second dialog", CController::createUrl('dialogTesting/openDialog2'),array('update' => '#data'));
?>
//_dialogContent1.php
<?php
 $this->beginWidget('zii.widgets.jui.CJuiDialog', array(
            'id'=>'mydialog1',
            'options'=>array(
                'title'=>'Dialog box 1',
                'autoOpen'=>true,
                'modal'=>true,
            ),
        ));
        echo 'first dialog content here';
        $this->endWidget('zii.widgets.jui.CJuiDialog');
?>

//_dialogContent2.php
<?php
 $this->beginWidget('zii.widgets.jui.CJuiDialog', array(
            'id'=>'mydialog1',
            'options'=>array(
                'title'=>'Dialog box 1',
                'autoOpen'=>true,
                'modal'=>true,
            ),
        ));
        echo 'first dialog content here';
        $this->endWidget('zii.widgets.jui.CJuiDialog');
?>

谢谢你的帮助

Kiran

命名文件
Yii中的约定是将视图文件命名为:

  • index.php:全视图
  • _dialog1.php:部分视图(从另一个视图包含)
<

子视图/strong>
然后您可以使用CController::renderPartial()包含部分视图:

$this->beginWidget(...);
$this->renderPartial('_dialog1', array('var1' => 23, 'var2' => "var"));
$this->endWidget(...);
<

分解代码/strong>
这将使您的源节点更轻。但我建议你更进一步,避免重复所有这些小部件调用。为此,您应该为您的对话框参数定义一个结构并在其上循环。比如:

$dialogs = array(
    'mydialog1' => array(
        'file' => '_dialog1',
        'options' => array('title' => "My title 1",),
    ),
    'mydialog2' => array(
        'file' => '_dialog12,
        'options' => array('title' => "My title 2",),
    ),
);
$defaultOptions = array(
    'autoOpen' => false,
    'modal' => true,      
);
foreach ($dialogs as $id => $dialog) {
    $this->beginWidget(
        'zii.widgets.jui.CJuiDialog',
        array(
            'id' => $id,
            'options' => CMap::mergeArray($defaultOptions, $dialog['options']),
        )
    );
    // ... include partial view ...

这种分解将使您的代码更加紧凑,但它将简化未来的更改。使用数据结构来避免代码重复是一个众所周知的做法。


最后,如果您真的希望动态加载部分视图,那就意味着必须使用AJAX。要小心,因为从用户的角度来看,您的页面可能反应性较差。如果所有表单都只有几Kb的HTML,那么就不需要AJAX。但是如果你这样做,那么你需要:

  • 添加只包含<div id="dialog-ajax"></div>的CJuiDialog。
  • 创建另一个动作,将renderPartial()应用于对话框视图
  • 将前面foreach循环的内容替换为编写JS的代码,如function dialog1() {jQuery("#dialog-ajax").load(...);}。如果你想动态地改变小部件的标题,你需要修改。
  • 绑定一些事件(点击)到这些JS函数。

另一种方法是让你的aJAX动作呈现一个完整的CJuiDialog,它可能更简单,避免JS攻击。无论如何,我不确定您是否真的需要AJAX。

我的答案

在控制器

//

   public function actionOpenDialog1()
{
    $data = array();
    $this->renderPartial('_dialogContent1', $data, false, true);
}
   public function actionOpenDialog2()
{
    $data = array();
    $this->renderPartial('_dialogContent2', $data, false, true);
}
在index.view

//

#数据));

echo html::ajaxButton("打开第二个对话框",CController::createUrl('dialogTesting/openDialog2'),array('update' => '#data'));?>

//_dialogContent1.php

$ this -> beginWidget("zii.widgets.jui。CJuiDialog’,阵列("id"=>"mydialog1’,"选项"=>阵列('title'=>'对话框1',"autoOpen ' =>真的,"模态"=>真的,),

);
    echo 'first dialog content here';
    $this->endWidget('zii.widgets.jui.CJuiDialog');

?>

//_dialogContent2.php

$ this -> beginWidget("zii.widgets.jui。CJuiDialog’,阵列("id"=>"mydialog1’,"选项"=>阵列('title'=>'对话框1',"autoOpen ' =>真的,"模态"=>真的,),

);
    echo 'first dialog content here';
    $this->endWidget('zii.widgets.jui.CJuiDialog');

?>

您可以简单地在页面中包含一个空的CJuiDialog,当它需要显示时,用jQuery AJAX加载内容(load是最简单的,可能足够了),在打开对话框之前返回适当视图的呈现

最新更新