Каков наилучший способ обработки сложных типов данных в CakePHP? - PullRequest
8 голосов
/ 05 ноября 2011

Моя цель: заменить средство выбора торта по умолчанию

Я ненавижу элементы выбора даты по умолчанию CakePHP FormHelper, и я бы хотел использовать вместо этого виджет DatePicker пользовательского интерфейса jQuery. Чтобы изящно ухудшить качество, я хочу, чтобы поле даты (включенное с виджетом) и поле выбора таймера выбирались с шагом 15 минут.

Если я объяснил это плохо, вот как это выглядит:

date-picker sample

Мое идеальное решение

Чтобы свести к минимуму повторение, я хочу поместить HTML-код в элемент макета и обработать его, используя функцию поведения. Таким образом, я мог сделать что-то вроде следующего:

view.ctp

echo $this->element( 'datepicker', array( 'data' => $data ) );

model.php

$actsAs = array( 'Datepicker' );

function beforeSave( $options ){
    $this->parseDatepickers();  //behavior function would alter $this->data
    return true;
}

Проблема

К сожалению, к тому времени, когда он получает обратный вызов beforeSave (или beforeValidate), поля datepicker и timepicker были уничтожены функцией deconstruct модели. deconstruct, кажется, ищет даты и время, о которых следует сообщать, как FormHelper их создает.

Короче, он ищет:

[date_field] => Array
(
    [year] => 2011
    [month] => 11
    [day] => 11
    [hour] => 8
    [min] => 00
    [meridian] => pm
)

но вместо этого он находит:

[date_field] => Array
(
    [datepicker] => 11/11/2011
    [timepicker] => 8:00 pm
)

И поскольку он не находит ожидаемую структуру, я получаю следующее:

[date_field] =>

Я знаю, что jQuery может обновлять скрытые входные данные с помощью полей с соответствующими именами, но это не ухудшится.

Текущее решение

На данный момент я выполняю очистку данных с помощью моей функции поведения перед сохранением, но это не похоже на правильный способ сделать это:

$this->request->data = $this->Event->fixDates( $this->data );
$this->Event->save( $this->data );

Так ...............

Каков наилучший способ сделать это? Помещение в beforeSave или beforeValidate выглядит как "Путь к пирогу", но deconstruct убивает меня. Нужно ли расширять AppModel и переопределять deconstruct? Это тоже кажется уродливым.

1 Ответ

2 голосов
/ 10 ноября 2011

Я обычно делаю свои поля даты как текстовые поля в представлении, чтобы переопределить вывод Помощника по умолчанию по умолчанию, а затем использую средство выбора даты jQuery (или любой другой альтернативный выбор), чтобы установить дату:

echo $this->Form->input('date', array('type' => 'text', 'class' => 'datepicker'));

Это выдает типичный тег, а не все раскрывающиеся списки.

Затем в функции beforeSave моей модели я изменяю формат на дату в формате MySQL:

$this->data['Model']['date'] = date('Y-m-d G:i:s', strtotime($this->data['Model']['date']));

(не забудьте вернутьtrue в beforeSave)

Это работает с правильным типом данных datetime в базе данных и похоже на то, что вы пытаетесь сделать.

...