jQuery 使用 AJAX 和 CakePHP 保存数据

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6285006/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-26 20:38:12  来源:igfitidea点击:

Save data using AJAX and CakePHP

jqueryajaxjquery-uicakephp

提问by Alex

I've spent today researching how to save data using an ajax request in cakephp and have got now where, the documentation on the cakephp website seems a bit lacking for this particular topic.

我花了今天研究如何在 cakephp 中使用 ajax 请求来保存数据,现在已经到了哪里,cakephp 网站上的文档似乎有点缺乏这个特定主题。

I have several sortable lists and I need to save the position of each list item when one is sorted. I have an ajax request set up as follows that is triggered when an item is moved:

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

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

and the referenced function in the controller is:

控制器中引用的函数是:

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

             SAVE STUFF...

        }
  }

I have the helpers etc. set up:

我有帮手等设置:

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

And its not working...

它不工作......

So my questions are:

所以我的问题是:

1) What is the current url for sending an ajax request to an action in a controller? Is it simply /controller/action?

1) 将 ajax 请求发送到控制器中的操作的当前 url 是什么?它只是/控制器/动作吗?

2) What else do I need to do to the controller to access the ajax data?

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

BONUS:

奖金:

3) Is there a way to include a custom php file in the CakePHP framework that references the database settings so I can manually update my mysql database?

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

回答by OpenSorceress

You were very close.

你非常接近。

1.) URL is simply /controller/action. Data is passed in $this->data and is magically available in the action. **Since you list 'Js' in your helpers instead of 'Javascript', I'm presuming you're using Cake 1.3.x and jQuery, because jQuery is the default with Cake 1.3 and Js replaced Javascript / Ajax.

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

-- Fix your helpers:

-- 修复你的助手:

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

-- Fix your jQuery:

-- 修复你的 jQuery:

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

2.) Use Cake's magic:

2.) 使用 Cake 的魔法:

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

-- Since you're doing ajax, you probably do NOT want Cake's default view-rendering behavior (just a guess.) If you want to render any view at all, it's probably just a snip of markup for an ajax callback, so you probably want to place it in an element rather than a full-blown view:

-- 因为你在做 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'); 
}

-- Otherwise, just suppress rendering:

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

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

-- If your save isn't working, make sure the structure of $this->data is Cake-save-friendly. If you need to view the contents of $this->data, Cake's built-in debugging (from anywhere in your app) will help you get straightened out:

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

debug($this->data);

3.) Wait, what?

3.) 等等,什么?

Not sure I understand what you're asking correctly, so if this does not cover your question, please clarify what you're trying to do?

不确定我是否正确理解您的要求,因此如果这未涵盖您的问题,请说明您要做什么?

If you mean, will Cake allow you to manually update records in a table/s, yes? Although I'm not sure why you would want to. Cake's extremely powerful built-in ORM is half the point of the framework, and its extremely comprehensive magic is the other half.

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

You can scribble off straight SQL with the Model::sql() method, although this is discouraged it's not very OOP or reusable.

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

When you define associations in your model, you can set the foreign key to false and specify conditions that work like a nested select in Cake's auto joins.

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

If you need to force join/s, Cake's $options['joins'] give you completely granular control; you can designate any type of JOIN if the default LEFT isn't good enough for what you need to do.

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

You can make and break model bindings on the fly with $this->Model->bind() / unbind(). You can specify the level of recursion, apply Containable behavior, specify the fields to select and all conditions.

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

If you need a subquery and Cake just can't get it right, $dbo->buildStatement() will construct your SQL statement and $dbo->expression() will fire it:

如果您需要一个子查询,而 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'));
    }

-- If you mean - will Cake allow you to swap out database configurations on the fly, yes. However, doing so can get pretty hardcore, especially when Cake's magic is part of the situation.

-- 如果您的意思是- Cake 是否允许您即时更换数据库配置,是的。但是,这样做可能会变得非常顽固,尤其是当 Cake 的魔法成为这种情况的一部分时。

You can add multiple db configs in /app/config/database.php -

您可以在 /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'
);
}

-- Switching between them in your controller / model is where things get a little intense, depending on the complexity of your situation:

-- 在您的控制器/模型中在它们之间切换是事情变得有点激烈的地方,具体取决于您的情况的复杂性:

// 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');
}

-- If this is what you meant, I can paste a chunk of code I wrote a couple weeks ago requiring I save an ajax form submission (at 2 stages of form completion) to 3 tables in 2 databases (one serving my Cake application, the other serving a legacy CodeIgniter application) showing all this fancy footwork in action along with some good old-fashioned Cake magic join-through save/update shortcuts. (I also had to generate selective emails and finally, fire off a REST request passing the id/s of the newly inserted records to the CI application to trigger it's processing. Whew!)

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

Anyway, HTH. :)

无论如何,HTH。:)

回答by Tim

  1. Yes, it's simple as that.
    1. To access the data like you sent it you can access the data with $this->dataas usual
    2. Why don't you use tools like phpmyadmin?
  1. 是的,就是这么简单。
    1. 要访问您发送的数据,您可以$this->data像往常一样访问数据
    2. 你为什么不使用像phpmyadmin这样的工具?

回答by Ashish pathak

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