【问题标题】:CakePHP + ajaxForm - load part of viewCakePHP + ajaxForm - 加载部分视图
【发布时间】:2013-02-02 19:36:01
【问题描述】:

我通过 jQuery 插件 AjaxForm 将表单提交到服务器。

这是我的简化视图:

<div id="output1">...here goes my CakePHP PHP form code...</div>

<script type="text/javascript">
    $(document).ready(function() { 
        var options = { 
            target:'#output1',
            beforeSubmit: onBeforeSubmit,
            success: onSuccess,
            error: onError
        }; 
        $('#CommentEditForm').ajaxForm(options); 
    });
</script>    

在我的控制器函数中,当我收到未经模型验证的表单数据时,我会更改 ajax 布局的布局并返回没有默认布局的 html 内容的视图,并将其附加到我的视图中的 div#output1 中。

似乎没问题,但现在除了 div#output1 和 javascript 代码之外,我已经看到了表单。我知道我的问题在哪里 - 我需要解决如何返回 only 表单数据而不是 javascript 代码和 div#output1 的东西。这个逻辑将在我的所有应用程序中使用,所以我想避免在我的所有视图中硬编码 {if...else} 条件。

【问题讨论】:

    标签: jquery ajax cakephp


    【解决方案1】:

    thaJezath 的回答很好,但还有一些事情:

    1. 使用 CakePHP Js helper 处理所有 ajax 内容更简单、更 DRY:

      <div id="output">
      <?php
          echo $this->Form->create();
          echo $this->Form->input('input1');
          echo $this->Form->input('input2');
          echo $this->Js->submit('submit',array('update' => '#output');
      ?>
      </div>
      

    这将自动添加为您处理 ajax 提交的缓冲脚本。但是您需要在布局中的 echo $this-&gt;Js-&gt;writeBuffer(); 行,就在 &lt;/body&gt; 标签之前。 但这仍然返回&lt;div id="output"&gt;... - 如果您将更改为'update' =&gt; '#content',它将重新加载整个内容div。

    1. 如果您确实需要更新表单而不是其他内容:

    在您的视图文件中:

         <div id="output">
         <?php $this->start('ajax-content'); // this line starts new block ?>
         <?php
            echo $this->Form->create();
            echo $this->Form->input('input1');
            echo $this->Form->input('input2');
            echo $this->Js->submit('submit',array('update' => '#output');
        ?>
        <?php
            $this->end(); // this line ends block
            echo $this->fetch('ajax-content'); // this line print contents of block
        ?>
        </div>
    

    在您的 /View/Layouts/ajax.ctp 中:

        <?php
            // next 2 lines only ensure that ajax-content block exists
            // if not it will be just empty string
            $this->startIfEmpty('ajax-content'); 
            $this->end();
            echo $this->fetch('ajax-content'); // this line outputs ajax-content block (the form)
        ?>
    

    因此,总而言之,此方法将您想要返回的内容包含在视图块内的 ajax 内容中。然后 ajax 布局而不是打印整个视图 ($this-&gt;fetch('content');) 它只打印 ajax-content 块的内容 ($this-&gt;fetch('ajax-content');)。这样您就可以在每个视图中标记您希望在 ajax 请求期间返回的所有内容。

    线条:

            $this->end(); // this line ends block
            echo $this->fetch('ajax-content'); // this line print contents of block
    

    可能不太方便 - 最好将所有块记录代码放在您自己的助手中以便简单地使用它:

        <div id=...
        $this->AjaxContent->start();
        your form here
        $this->AjaxContent->stop();
        </div>
    

    正如 thaJezath 在 cmets 中所写,JsHelper 将在未来的版本中被弃用,因此如他所说,使用视图块会更安全。 HtmlHelper 有方便的方法:

        <?php $this->Html->scriptStart(array('inline' => false)); ?>
            $(document).ready(function(){ 
                // your code here
            });
        <?php $this->Html->scriptStart(array('inline' => false)); ?>
    

    这会将您的脚本添加到由$this-&gt;fetch('script');以默认布局打印的viewBlock "script"

    【讨论】:

    • 我不是 JsHelper generating javascript 的忠实粉丝,因为它的功能非常有限。另请注意,JsHelper 在 CakePHP 3 中将被弃用,所以不要过分依赖它。
    • 不知道 - 在 Cake 3 中会有一些东西代替 JsHelper?
    • CakePHP 开发人员得出的结论是,由于(例如)jQuery 中的 API 发生了变化,通过 PHP“生成”javascript 很难维护。此外,它在可能的方面不是很灵活/有限。因此他们决定放弃它。添加 javascript 的最佳方式是自己编写代码,可选择通过 PHP 插入“选择器”。如果要“缓冲”要添加到布局的 javascript,请使用视图块。并且(最后一点)使用事件委托/冒泡(使用 jQuery.on())通常优于将事件处理程序附加到单个元素
    • 这是来自 ADmad 的回复,他是 CakePHP 团队的核心开发人员:stackoverflow.com/questions/12885270/…
    【解决方案2】:

    您应该使用 JavaScript 缓冲区或“视图块”来输出您的 JavaScript,这样您就可以输出 javascript 在您的布局内,而不是在您的视图中。因为您已经切换到不同的布局(或没有布局) 对于您的 AJAX 请求,通过 AJAX 检索时不会包含该脚本。

    改变你的观点:

    将视图的内容修改为:

    <div id="output1">...here goes my CakePHP PHP form code...</div>
    
    <?php
    
    /**
     * I'm using 'heredoc' notation so that you don't have to escape quotes and '$'
     * @link http://www.php.net/manual/en/language.types.string.php#language.types.string.syntax.heredoc
     */
    $script = <<< JS
        $('#CommentEditForm').ajaxForm({ 
            target:'#output1',
            beforeSubmit: onBeforeSubmit,
            success: onSuccess,
            error: onError
        }); 
    JS;
    
    /**
     * Append the JavaScript to the JavaScript-buffer
     * using the JS helper
     * 
     * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/js.html
     */
    $this->Js->buffer($script);
    

    在您的布局中输出 JavaScript(例如 Layouts/default.ctp)

    <!-- rest of your layout here -->
    
    <?php
    // Output the JavaScript and wrap it in a 'onDomready()' wrapper
    echo $this->Js->writeBuffer();
    ?>
    </body>
    </html>
    

    注意: 使用 JS 缓冲区时,您不必将“onDomready()”添加到脚本中, CakePHP 会在使用 $this->Js->writeBuffer()

    输出缓冲区时自动添加它们

    注意2: 使用输出缓冲区允许您将 JavaScript 多次添加到缓冲区。 例如,如果您使用“元素”,则可以将 javascript 添加到 缓冲也是如此。这允许您添加脚本'as-you-go'并将它们全部输出 一次在你身体的尽头

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-05-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-06-30
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多