2011-06-08 61 views
10

我已经花费了今天的研究如何在cakephp中使用ajax请求保存数据,并且现在已经到了哪里,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是什么?它只是/控制器/操作?

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

奖金:

3)有没有一种方法,包括在CakePHP的框架引用数据库设置,所以我可以手动更新我的MySQL数据库自定义的PHP文件?

回答

24

你非常接近。

1.)URL简单地是/控制器/动作。数据通过$ this->数据传递,并且在动作中神奇地可用。 **因为你在助手而不是'Javascript'中列出'Js',所以我假设你使用的是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-friendly。如果您需要查看的$这个 - 内容>数据,Cake的内置调试(从您的应用程序的任何地方)将帮助你理顺:

debug($this->data); 

3)等等,什么?

不知道我明白你问的是正确的,所以如果这不包括你的问题,请澄清你想要做什么?

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

你可以用Model :: sql()方法直接写SQL,虽然这不鼓励它是OOP或可重用的。

当您在模型中定义关联时,可以将外键设置为false,并指定在Cake的自动连接中像嵌套选择一样工作的条件。如果你需要强制连接/ s,Cake的$ options ['joins']会给你完全细化的控制;你可以指定任何类型的JOIN,如果默认的LEFT不足以满足你需要做的事情。

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

如果你需要一个子查询和蛋糕只是无法得到它的权利,$ dbo-> buildStatement()将构建SQL语句和$ dbo->表达式()会火了:

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添加多个分贝CONFIGS -

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个阶段形式完成),以3个表在2个数据库中(一个服务于我的Cake应用程序,另一个服务于传统的Cod eIgniter应用程序)展示了所有这些花哨的步法以及一些优秀的老式Cake魔术连接保存/更新快捷键。 (我还必须生成有选择的电子邮件,并最终发出REST请求,将新插入的记录的ID传递给CI应用程序以触发其处理。)

无论如何,HTH。 :)

+0

非常感谢您的帮助!我已经做了你所说的更改,但是现在我从ajax请求中获得了404错误。我更接近让它工作,这要归功于你,还有什么想法404可能会降低到什么程度?回覆。 3)你绝对正确,它不是很蛋糕,我完全忘了自定义的sql语句 - 我将自定义sql看作是一个标志,我做错了,现在我不需要使用它!也是你的权利,即时通讯使用JQuery和蛋糕1.3。 – Alex 2011-06-09 16:20:37

+3

Np。错误404通常表示某些内容已关闭 - 可能是权限,还是错字路由?否则Cake会丢失Controller/Action/View/whatever。任何时候Cake都会咳嗽一个404,我直接去看我的错误日志 - 首先是Cake,然后是Apache的 - 看看它试图拉取什么。检查所有权/权限,查找文件/类名中的错别字,所有小东西。如果您使用Auth,请将您的ajax控制器操作添加到允许的列表中。 Cake的debug()是一个救生员,没有什么比FirePHP(整合Cake)更好的调试蛋糕ajax问题。 – OpenSorceress 2011-06-09 16:53:50

+0

你是救星和英雄!我有一个愚蠢的网址问题,给了我404。非常感谢。 – Alex 2011-06-09 16:58:50

0
  1. 是的,这很简单。
    1. 要访问数据就像你送它,你可以用$this->data照常
    2. 你为什么不使用工具,如phpmyadmin访问数据?
+0

phpMyAdmin是一个安全噩梦。完全不适合生产服务器。 IME,最后的选择/临时解决方案的团队开发服务器。 **另外,直接访问数据库操作解决方案实际上只适用于开发人员类型的用户。**在无限现实场景中,应用程序必须解决需要复杂/异乎寻常的数据库和数据源设置和操作。我的项目 - >完美的例子:目前的淘汰/迁移阶段意味着处理Cake和CI的dbs。 2个框架,2个数据库/服务器(略有不匹配的表格!),3个模型,白名单,重新加载模式等... – OpenSorceress 2011-06-10 12:00:16

0
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(); 
     } 
    } 
} 
+0

在控制器中添加此代码/ *** @akki ** / – 2014-07-17 05:04:05