Сохраняйте данные, используя AJAX и CakePHP - PullRequest
9 голосов
/ 09 июня 2011

Я потратил сегодня на изучение того, как сохранить данные с помощью ajax-запроса в cakephp, и получил информацию о том, где документация на сайте 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) Какой текущий URL-адрес для отправки ajax-запроса к действию в контроллере? Это просто / контроллер / действие?

2) Что еще мне нужно сделать с контроллером для доступа к данным ajax?

БОНУС:

3) Есть ли способ включить пользовательский php-файл в платформу CakePHP, который ссылается на настройки базы данных, чтобы я мог вручную обновить свою базу данных mysql?

Ответы [ 3 ]

23 голосов
/ 09 июня 2011

Вы были очень близки.

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.) Используйте магию торта:

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 ориентирована на сохранение тортов. Если вам нужно просмотреть содержимое $ this-> data, встроенная отладка Cake (из любой точки вашего приложения) поможет вам разобраться:

debug($this->data);

3.) Подождите, что?

Не уверен, что я правильно понимаю, что вы спрашиваете, поэтому, если это не относится к вашему вопросу, уточните, что вы пытаетесь сделать?

Если вы имеете в виду, позволит ли Cake вручную обновлять записи в таблице / таблицах, да? Хотя я не уверен, почему ты этого хочешь. Чрезвычайно мощная встроенная ORM Cake - это половина сути фреймворка, а его чрезвычайно всеобъемлющее волшебство - другая половина.

Вы можете набросать прямой SQL с помощью метода Model :: sql (), хотя это не рекомендуется, так как он не очень ООП и не может использоваться повторно.

Когда вы определяете ассоциации в вашей модели, вы можете установить для внешнего ключа значение false и указать условия, которые работают как вложенный выбор, в автоматических объединениях Cake.

Если вам нужно форсировать join / s, $ options [Cake '] в Cake дает вам полный контроль; Вы можете назначить любой тип JOIN, если LEFT по умолчанию недостаточно хорош для того, что вам нужно сделать.

Вы можете создавать и разрывать привязки моделей на лету с помощью $ this-> Model-> bind () / unbind (). Вы можете указать уровень рекурсии, применить поведение Containable, указать поля для выбора и все условия.

Если вам нужен подзапрос, а 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 этапах заполнения формы) в 3 таблицы в 2 базах данных (одна обслуживает мой Приложение Cake, другое, обслуживающее унаследованное приложение CodeIgniter), демонстрирующее всю эту сложную работу в действии, а также несколько старых добрых волшебных сочетаний клавиш Cake для сохранения / обновления. (Мне также пришлось сгенерировать отдельные электронные письма и, наконец, запустить REST-запрос, передавая идентификаторы вновь вставленных записей в приложение CI для запуска его обработки. Вот так!)

Во всяком случае, HTH. :)

0 голосов
/ 17 июля 2014
 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 голосов
/ 09 июня 2011
  1. Да, все просто.
    1. Для доступа к данным, которые вы отправили, вы можете получить доступ к данным с помощью $this->data как обычно
    2. Почему вы не используете такие инструменты, как phpmyadmin ?
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...