在cakephp中重新渲染元素视图后,如何重新绑定javascript事件

时间:2015-05-15 15:39:47

标签: javascript jquery html ajax cakephp

我的情况概述 -

我有一个包含2个表的数据库。第一个表称为' primary_content_areas',第二个表称为' secondary_content_areas'。唯一需要注意的重要事项是每个都包含一个ID和' secondary_content_areas' table有一个名为primary_content_area_id的字段。 primary_content_areas模型与secondary_content_areas具有hasMany关系。

使用Cakephp框架,我有一个名为Primary的元素视图,其中包含一个div。在div内部,有一个foreach循环,它循环从控制器传入的数据,并根据有多少secondary_content_areas具有等于当前primary_content_area id的primary_content_area_id来创建div。数据库基本上创建了一个树结构,然后递归循环并在div中绘制div。目前它只有2层。一个'添加'按钮也位于“小学”内。元素视图。单击此添加按钮时,使用jquery在secondary_content_areas表中创建一个新对象,并指定字段" primary_content_areas_id'到添加按钮所属的div的ID。然后在同一个jquery进程中,如果成功,它会在控制器中加载一个函数,重新呈现' Primary'元素视图。由于它是如何设置的,这实际上重新呈现来自“主要”的每个div。 div也是所有辅助div连接的。

我的问题 -

我有这个工作。我的问题是,在我点击一次按钮后,它会添加一个' secondary'对象到数据库,并呈现一个新的div,但之后该按钮不起作用。经过一些研究,我认为这与重新渲染视图的事实有关,更具体地说是“添加”视频。使用jquery的按钮基本上解除了DOM中的所有事件的绑定。

所以我的问题是如何使用cakephp重新绑定我的jquery事件。

这是代码。

控制器----

...

public function add_secondary () {


    $this->layout = 'ajax';
    // check user is logged in
    if($this->Session->read('Auth.User'))
    {
        $this->Secondary->create();
        $content_area_id = $this->request->data['primary_content_area_id'];
        $this->Secondary->set('primary_content_area_id', $content_area_id);
        $this->Secondary->set('position', '1');


        if ($this->Column->save($this->request->data))
            {

                $result = array('result' => 'success', 'text' => 'Column Added');

            }
    }

    echo json_encode($result);
    die();

}

public function ajax_render () {
        $this->Primary->recursive = 5;
        $page_data = $this->Primary->find('first',array('conditions' => array('Primary.name' => 'index' ))); //temporary
        $this->set('page_data', $page_data);
        $this->render('/elements/primary');
    }
...

我最好的猜测是,我感觉自己需要一条线路。 $这 - >呈现(' /元件/初级&#39); '这叫我的' bindEvents(); '我的Js功能。虽然使用了cakephp,但我还没有找到从控制器调用js函数的方法。

主要元素视图---

<?php foreach($page_data['ContentArea'] as $contentArea){  ?>
<div class="content_area <?php echo $contentArea['tags'] ?>" >
    <?php echo $this->element('secondary', array( "contentArea" => $contentArea));?>
    <div class="button_container">
        <div class="add_button content_area_add_button">
            <input class="add_content_area" id="add_content_area" type="submit" value="add" data-content-area-id="<?php echo $contentArea['id']?>" />
        </div>
    </div>
</div>

JS ----

function bindEvents() {
$("#add_content_area").click(function() {
    //alert($(this).data("content-area-id"));
    var request = $.ajax({
        type: "POST",
        url: "/pages/add_secondary/",
        dataType: "json",
        data: { content_area_id: $(this).data("content-area-id") }
    });

    request.done(function(result) {
        if(result.result == "success")
        {
            alert( "success" );
            $('#content').load('/pages/ajax_render/', function() {
                alert( "Load was performed." );
            });
        }
        else
        {
            alert("Comment " + result.result + ": " + result.text);
        }
    });

    request.fail(function(jqXHR, textStatus) {
        alert("Request failed: " + textStatus);
    });

});

}


$(document).ready(function() {
    bindEvents();
});

PS。警报(&#34;已执行加载。&#34;)&#39;没有发生。我相信我的语法是正确的,它意味着在完成加载时提醒该消息。它没有。

3 个答案:

答案 0 :(得分:1)

考虑使用来自父元素的事件委托(不会更改),而不是重新绑定事件,那么您将不需要重新绑定任何内容:

$("body").on('click', '#add_content_area', function(){
  .. do stuff
});

答案 1 :(得分:0)

尝试将JS代码放在一个文件中,并在afterRender()函数中调用它

function afterRender() 
{
  echo $this->Html->script('UR JS', array('inline'=>false));
}

答案 2 :(得分:0)

好的,所以我不确定这与其他人有多相关,但我想发布我如何解决这个问题。事实证明我忘记了it{ bad_user = create(:user, password: 'passworD1') 3.times do post :create, user: { email: bad_user.email, password: 'asdf' } end post :create, user: { email: bad_user.email, password: 'asdf' } bad_user.reload expect(bad_user.failed_attempts).to eq(4) expect(bad_user.locked_at).not_to be_blank } 中的$this->layout = 'ajax';行。一旦我加入,public function ajax_render();就发生了。相反,我用alert( "Load was performed." );替换了该警报,所以在我的ajax_render函数加载完成后,它再次调用了bindEvents()。