2

フォームと検証がすべて従来のポストバックを使用して正しく機能するCakePHP(最新バージョン)Webアプリがありますが、現在、いくつかのフォームをajax経由で送信するように切り替えています。検証エラーが発生した場合は、次のようにフォーマットされたJSONとしてクライアントに戻したいと思います。

{
"success":false,
"errors":{
    "data[User][username]":["This is not a valid e-mail address"],
    "data[User][password]":["You must choose a password"]
}}

エラー配列のキーは、フォームフィールドのname属性に対応している必要があります。このようにフォーマットされたJSONを期待するビルド済みのクライアントスクリプトがいくつかあります。幸いなことに、これはCakePHPのvalidationErrorsオブジェクトの外観に非常に近いものです。だから私は現在私のコントローラーでこれを行っています:

if ($this->User->save($this->request->data)) {

} else {
    if ($this->request->is('ajax')) {
        $this->autoRender = $this->layout = false;
        $response['success'] = false;
        $response['errors'] = $this->User->validationErrors;
        echo json_encode($response);
        exit(0);
    }
}

ただし、JSON応答は次のようになります。

{
"success":false,
"errors":{
    "username":["This is not a valid e-mail address"],
    "password":["You must choose a password"]
}}

エラーキーには、基本的なデータベーステーブルのフィールド名だけが含まれていることに注意してください。これらは、FormHelperが通常処理するdata[User][username]形式に変換されません。

配列を返す前に配列を調整する簡単な方法はありますか?「data[User]」は十分に堅牢ではないため、単純にループして先頭に追加したくありません。1つの場所に配置して、さまざまなモデルのさまざまなコントローラーから呼び出すことができるコードが欲しいのですが。FormHelperは入力名属性を考え出すために何を使用しますか?それを利用できますか?どういうわけかJSONビューを使用する必要がありますか?

4

3 に答える 3

2

これは、$validationErrors配列がフォーマットされる方法だからです。ループする必要がある出力を取得するには、それを回避する方法はありません。

foreach ($this->User->validationErrors as $field => $error) {
  $this->User->validationErrors["data[User][$field]"] = $error;
  unset($this->User->validationErrors[$field]);
}

代わりに、すべてのエラーをに渡すことをお勧めしjson_encode()ます。$this->validationErrorsビューで利用可能なそのリクエストのすべてのモデル検証エラーの組み合わせリストです(レンダリング後にコンパイルされます)。表示ロジック(jsonをエコーする)をビューに移動し、そこでループする必要があります。

ビューで

$errors = array();
foreach ($this->validationErrors as $model => $modelErrors) {
  foreach ($modelErrors as $field => $error) {
    $errors["data[$model][$field]"] = $error;
  }
}
$response['errors'] = $errors;
echo json_encode($response);

これは次のようなものを出力します:

{
  "success":false,
  "errors": [
      "data[User][username]": "This is not a valid e-mail address",
      "data[User][password]": "This is not a valid password",
      "data[Profile][name]": "Please fill in the field"
  ]
}
于 2012-09-13T20:58:20.383 に答える
1
I have created a small recursive function to create validation error as a string with column name so that can be passed as json object.

 /**
     * prepare erorr message to be displayed from js
     *
     * @param array   $errors  validation error array
     * @param stringn $message refernce variable
     *
     * @return void
     */
    public function parseValidationErrors($errors, &$message)
    {
        foreach ($errors as $columnName => $error) {
            $message .= "<strong>$columnName:</strong> ";
            foreach ($error as $i => $msg) {
                if (is_array($msg)) {
                    $this->_parseValidationErrors($msg, $message);
                } else {
                    $message .= str_replace("This field", "", $msg . " ");
                    isset($error[$i + 1]) ? $message .= " and " : $message;
                }
            }
        }
    }

コントローラコードは次のようになります。

if (!$this->YourModel->saveAll($modelObject)) {
                $errors = $this->YourModel->validationErrors;
                $message = '';
                $this->parseValidationErrors($errors, $message);
                $response = array('status' => 'error', 'message' => $message);
            }
于 2016-09-28T06:54:59.857 に答える
0
$response['errors']['User'] = $this->User->validationErrors;
于 2013-09-27T08:29:25.753 に答える