是否有一种标准方法来处理仅在 MVC 中的一个视图中使用的 javascript


Is there a standard way of dealing with javascript only used in one view in MVC?

这是我第一次尝试MVC。 我正在使用 MVC 的代码点火器以及前端的 jQuery 和 jQueryUI。 我有MVC的基本概念,我有一个工作网站。 不过,从概念上讲,我想确保我对MVC的想法尽可能保持严格。

我有一个主皮肤视图,然后使用load->view("skin", $contents)其中$contents是包含其他视图的关联数组。

结果,我有一个页面(称为"管理控制台"(,其中调用了皮肤视图,$content包含更多 HTML。 我希望仅在该页面上使用jQueryUI对话框。 为了创建它,我有一个<script>标签,其中包含管理控制台视图中的对话框 javascript。 这最终会在一堆 HTML 中间有一个 <script> 标记,其中包括呈现最终页面的时间。

这样做的最终结果是我懒惰地加载javascript,但它可能会导致多个jQuery $(document).ready(function(){...});调用。

我一切正常,但我不确定我的实现是否符合 MVC 原则。 使用我正在使用的方法更好,其中javascript仅在使用时加载,还是应该将javascript放在其他地方? 我是在用鼹鼠山造山吗?


我的相关控制器代码:

function index(){
$tree = $this->mainModel->getUnitTreeMeta();
$treeOutput = $this->load->view('unit_tree', array('units' => $tree), TRUE);
$pages = $this->mainModel->getPages();
$console = $this->load->view('admin_console', array('units'=>$tree, 'pages'=>$pages), TRUE);
$content = array(
    'title'         =>  'Admin Console',
    'css'           =>  link_tag(array('href' => 'css/admin.css', 'rel' => 'stylesheet', 'type' => 'text/css', 'media'=> 'screen'))."'n",
    'navbar'        =>  'navbar',
    'content'       =>  $console,
    'rightSidebar'  =>  $treeOutput,
    'footer'        =>  ''
);
$this->load->view('skin', $content);
}

skin.php 包含行<?=$content?>,即包含在admin_console视图中的 HTML/JS:

<div>
    <div>
        ...
        <a href="" id="addUnit" class="smallLinks">Add a New Unit</a>
    </div>
</div>
<!-- DIALOG BOXES -->
<div id="addUnitDialog" title="Add A New Unit">
    <?php echo form_open('admin/add_unit'); ?>
    Unit Name: <br />
    <?php echo form_input("unitName", "");?>
    <br />
    Content: <br />
    <?php echo form_textarea("content", "");?>
    <?php echo  form_close();?>
    <div id="addUnitResponse"></div>
</div>
<script type="text/javascript">
    $(document).ready(function(){
        $( "#addUnitDialog" ).dialog({
            autoOpen: false,
            minWidth: 680,
            buttons: {
                "add Unit" : function(){
                    var unitName = $("input", this).val();
                    var content = $("textarea", this).val();
                    $.ajax({
                        url : "add_unit",
                        type : "POST",
                        success :function(){
                            location.reload();
                        },
                        error : function(){
                            $("#addUnitResponse").text("error");
                        }
                    });
                }
            }           
        });
        $("a#addUnit").click(function(){
            $( "#addUnitDialog" ).dialog( "open" );
            return false;       
        });
    });
</script>

就我个人而言,我已经放弃了JS永远不应该出现在HTML中的观点。但是,我通常做这种事情的方式是在视图的<头>包含一个"if(isset(..."块:

// You may choose to have non-array implementations...
if(isset($js_array))
{
    foreach($js_array as $file)
    {
        if(strpos($file, '.'))
             echo "<script type='"text/javascript'" src='"$file'" />" . PHP_EOL;
        else
             echo "<script type='"text/javascript'">$file</script>" . PHP_EOL;
    }
}

这里的缺点是它需要控件知道视图如何呈现不同的内容。当然,这可以通过创建一个文件来解决,admin.php文件中有两行:

 $js_array = array('/custom_js.js');
 require_once('skin.php'); //<-- will cause issues if your server does not 
                           //    allow short tags, but CodeIgniter is parsing 
                           //    them for you. (I find that bad anyway...)

您需要调用$this->load->view('admin', $content);,但这是一个微小的变化。