【问题标题】:Save data using AJAX and CakePHP使用 AJAX 和 CakePHP 保存数据
【发布时间】:2011-09-11 05:12:18
【问题描述】:

我今天花了很多时间研究如何在 cakephp 中使用 ajax 请求来保存数据,现在我知道了,cakephp 网站上的文档似乎有点缺乏这个特定主题。

我有几个可排序的列表,我需要在排序时保存每个列表项的位置。我有一个 ajax 请求设置如下,在移动项目时触发:

$.ajax({                    
        url: "/orders/save_column_order",
        type:"POST",                                        
        data:"data="+data
       });

控制器中引用的函数是:

function save_column_order(){
    if($this->RequestHandler->isAjax()){

             SAVE STUFF...

        }
  }

我已经设置了助手等:

var $helpers = array('Html','Form','Js');
var $components = array('Session','Email','RequestHandler');

而且它不工作......

所以我的问题是:

1) 向控制器中的操作发送 ajax 请求的当前 url 是什么?是简单的 /controller/action 吗?

2) 我还需要对控制器做什么才能访问 ajax 数据?

奖金:

3) 有没有办法在 CakePHP 框架中包含一个引用数据库设置的自定义 php 文件,以便我可以手动更新我的 mysql 数据库?

【问题讨论】:

    标签: jquery ajax jquery-ui cakephp


    【解决方案1】:

    你们很亲密。

    1.) URL 就是 /controller/action。数据在 $this->data 中传递,并且神奇地在操作中可用。 **由于您在帮助程序中列出了“Js”而不是“Javascript”,我假设您使用的是 Cake 1.3.x 和 jQuery,因为 jQuery 是 Cake 1.3 的默认值,而 Js 取代了 Javascript/Ajax。

    -- 修复你的助手:

    var $helpers = array('Html', 'Form', 'Js'=>array("Jquery"));
    

    -- 修复你的 jQuery:

    $.ajax({
        url:'/orders/save_column_order',
        type:'POST',
        data:data
    });
    

    2.) 使用 Cake 的魔法:

    function save_column_order() {
        if ($this->data != null) {
            $this->Model->save($this->data);
        // whatever else needs doing...
        }
    }
    

    -- 因为你在做 ajax,你可能不想要 Cake 的默认视图渲染行为(只是一个猜测。)如果你想渲染任何视图,它可能只是一个 ajax 回调的标记片段, 所以你可能想把它放在一个元素中而不是一个完整的视图中:

    function save_column_order() {
        // ...
        /* arg 1 - you can specify any view or element you like. 
           arg 2 - enforces your preferred request handling and layout */
        $this->set(compact('vars', 'for', 'view'));
        $this->render('/elements/new_column_order', 'ajax'); 
    }
    

    -- 否则,只是抑制渲染:

    function save_column_order() {
        ...     
        $this->autoRender = false;
    }
    

    -- 如果您的保存不起作用,请确保 $this->data 的结构对 Cake-save 友好。如果您需要查看 $this->data 的内容,Cake 的内置调试(从您应用程序的任何位置)将帮助您理顺:

    debug($this->data);
    

    3.) 等等,什么?

    不确定我是否正确理解您的问题,所以如果这不能涵盖您的问题,请说明您要做什么?

    如果您的意思是,Cake 是否允许您手动更新表中的记录,是吗?虽然我不确定你为什么想要。 Cake 极其强大的内置 ORM 是框架的一半,它极其全面的魔力是另一半。

    您可以使用 Model::sql() 方法直接写出 SQL,尽管不鼓励这样做,因为它不是非常 OOP 或可重用。

    当您在模型中定义关联时,您可以将外键设置为 false 并指定像 Cake 的自动连接中的嵌套选择一样工作的条件。

    如果你需要强制 join/s,Cake 的 $options['joins'] 给你完全精细的控制;如果默认的 LEFT 不足以满足您的需要,您可以指定任何类型的 JOIN。

    您可以使用 $this->Model->bind() / unbind() 即时创建和中断模型绑定。您可以指定递归级别、应用可包含行为、指定要选择的字段和所有条件。

    如果您需要一个子查询,而 Cake 无法正确处理,则 $dbo->buildStatement() 将构建您的 SQL 语句,而 $dbo->expression() 将触发它:

    function intricate() {
        $dbo = $this->Rate->Status->getDataSource();
        $subquery = $dbo->buildStatement(
            array(
                'fields' => array('`Status`.`id`'),
                'table' => $dbo->fullTableName($this->Rate->Status),
                'alias' => 'Status',
                'limit' => null,
                'offset' => null,
                'joins' => array(),
                'conditions' => $subqueryConditions,
                'order' => null,
                'group' => null
                ),
            $this->Rate->Status
            );
        $subquery = "Status.id = (".$subquery.")";
        $status = $dbo->expression($subquery);
        $options['fields']=
            array(
                "Rate.id", "Rate.plan_id", "Rate.status_id","Rate.rate", "Plan.id", 
                "Plan.company_id", "Plan.name", "Company.id", "Company.name"
            );
        $options['conditions']=
            array(
                $status, 
                "Geographical.name LIKE '%{$this->zip}%'"
            );
        $rates = $this->Rate->find('all', $options);
        $this->set(compact('rates'));
        }
    

    ——如果你的意思是——Cake 是否允许你即时交换数据库配置,是的。但是,这样做可能会变得非常顽固,尤其是当 Cake 的魔法是其中的一部分时。

    您可以在 /app/config/database.php 中添加多个数据库配置 -

    class DATABASE_CONFIG {
        var $default = array(
            'driver' => 'mysql',
            'persistent' => false,
            'host'=>'localhost',
            'login' => 'cake',
        'password' => 'icing',
            'database' => 'dev'
    );
        var $offsite = array(
            'driver' => 'mysql',
            'persistent' => false,
            'host' => '11.22.33.44', // or whatever
            'login' => 'cake',
            'password' => 'frosting',
            'database' => 'live'
    );
    }
    

    -- 根据您的情况的复杂性,在您的控制器/模型中切换它们会变得有点紧张:

    // Model::getDataSource()->configKeyName holds whichever db config you're using
    if ($this->Model->getDataSource()->configKeyName != 'default') {
        // do something, for example, change models, tables, reload schema, etc.
        $this->loadModel('Special')
        $this->Model->table = 'extras';
        $this->Model->schema(true);
    } else {
        // predictably, Model::setDataSource($configKey) changes configs
        $this->Model->setDataSource('offsite');
    }
    

    -- 如果这是你的意思,我可以粘贴我几周前写的一段代码,要求我将 ajax 表单提交(在表单完成的 2 个阶段)保存到 2 个数据库中的 3 个表(一个为我的Cake 应用程序,另一个服务于旧版 CodeIgniter 应用程序)展示了所有这些花哨的步法以及一些很好的老式 Cake 魔术连接保存/更新快捷方式。 (我还必须生成选择性电子邮件,最后,触发一个 REST 请求,将新插入的记录的 id/s 传递给 CI 应用程序以触发它的处理。哇!)

    无论如何,HTH。 :)

    【讨论】:

    • 非常感谢您的帮助!我已经进行了您所说的更改,但是我现在从 ajax 请求中收到了 404 错误。多亏了你,我离让它工作更近了,知道 404 可能是什么吗?回覆。 3)你绝对正确,它不是很蛋糕,我完全忘记了自定义 sql 语句 - 我认为自定义 sql 是我做错了什么的标志,现在我不需要使用它!还有你的权利,我正在使用 JQuery 和 cake 1.3。
    • Np。错误 404 通常表示某些东西已关闭 - 可能是权限,还是路由错误?否则 Cake 会抛出 Missing Controller / Action / View / 不管什么。每当 Cake 发出 404 错误时,我都会直接查看我的错误日志——首先是 Cake 的,然后是 Apache 的——看看它试图提取什么。检查所有权/权限,查找文件/类名中的拼写错误,所有这些小东西。如果您使用的是 Auth,请将您的 ajax 控制器操作添加到您的允许列表中。 Cake 的 debug() 是救命稻草,在调试 cake ajax 问题方面,没有什么比 FirePHP(与 Ca​​ke 集成)更好的了。
    • 你是救生员和英雄!我有一个愚蠢的 url 问题,给了我 404。非常感谢。
    【解决方案2】:
    1. 是的,就这么简单。
      1. 要访问您发送的数据,您可以像往常一样使用$this->data 访问数据
      2. 为什么不使用phpmyadmin 之类的工具?

    【讨论】:

    • phpMyAdmin 是一场安全噩梦。完全不适合生产服务器。 IME,团队开发服务器的最后选择/临时解决方案。 此外,直接访问 db manip 解决方案实际上只适合开发人员类型的用户。 在无限的现实场景中,应用程序必须解决复杂/奇异的数据库和数据源设置和操作的需求。我的项目-> 完美示例:当前的逐步淘汰/迁移阶段意味着同时处理 Cake 和 CI 的数据库。 2 个框架、2 个数据库/服务器(表略有不匹配!)、3 个模型、白名单、重新加载模式等......
    【解决方案3】:
     public function add_project() {
        $this->autoRender = false;
        $this->layout = 'ajax';
        if ($this->RequestHandler->isAjax()) {
            $this->Project->set($this->request->data);
            $this->request->data['Project']['user_id'] = $this->Session->read('Auth.User.id');
            $this->request->data['Project']['created_by'] = $this->Session->read('Auth.User.id');
            $this->request->data['Project']['updated_by'] = $this->Session->read('Auth.User.id');
            //$this->request->data['Skill']['accept_decline'] = 0;
            $this->User->set($this->request->data['Project']);
            Configure::write('debug', 0);
            if ($this->Project->validates(array('fieldList' => array('project_title', 'show_on', 'summary')))) {
    
                if ($this->Project->save($this->request->data, false)) {
                    $response['status'] = 'succses';
                    $response['message'] = 'data  sent';
                    echo json_encode($response);
                    exit();
                } else {
                    $response['status'] = 'error';
                    $response['model'] = 'Project';
                    $response['message'] = 'data not sent';
                    echo json_encode($response);
                    exit();
                }
            } else {
                $response['status'] = 'invalid';
                $response['model'] = 'Project';
                $errors = $this->Project->validationErrors;
                $response['errors'] = $errors;
                echo json_encode($response);
                exit();
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2014-05-20
      • 1970-01-01
      • 1970-01-01
      • 2011-09-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-14
      相关资源
      最近更新 更多