Ethna で Ajax する

長年 Ethna を使ってきて、Ajax するときの実装が各位バラバラだなっていつも思っていた。これぞ正しい実装!ってのがないかなーってなんとなく思ってきたんだけど、この度ついに解決。php 側でエラー時にステータスコード 500 番を返すのがポイント!

良いところは Ethna のバリデートやテンプレートがそのまま使える。デバッグもしやすい。javascript 側でレスポンスの中身を見て判別したりエラーメッセージを考える必要がない。MVC っぽい。


■データを保存する

javascript

var formData = new FormData();
formData.append('action_ajax_hoge_save', 'true');
formData.append('data', 'データ');

$.ajax({
url: './ajax.php',
type: 'POST',
contentType: false, // FormData を扱うのに必要
processData: false, // FormData を扱うのに必要
data: formData,
success: function(message) {
alert(message);
},
error:function(XMLHttpRequest, textStatus, errorThrown) {
alert(XMLHttpRequest.responseText);
}
});

php Action

class Sample_Action_AjaxHogeSave extends Wataca_ActionClass
{
public function prepare()
{
if ($this->af->validate() > 0) {
return 'ajax_error'; // バリデートエラーはエラーのビューへ
}
return null;
}

public function perform()
{
$HogeMgr = $this->backend->getManager('Hoge');
$HogeMgr->save($this->af->getArray());
$this->af->setApp('message', '保存しました');
return 'ajax_success'; // 問題なく処理されたら成功のビューへ
}
}


□バリデートエラーの場合

php View

class Wataca_View_AjaxError extends Wataca_AjaxViewClass
{
public function preforward()
{
header('HTTP', true, 500); // ここポイント
}
}

php template

{foreach $errors as $error}
{$error}
{/foreach}


□成功した場合

php View

class Wataca_View_AjaxSuccess extends Wataca_AjaxViewClass
{
public function preforward()
{
}
}

php template

{$app.message}


■データを JSON で取得する

javascript

var formData = new FormData();
formData.append('action_ajax_hoge_load', 'true');

$.ajax({
url: './ajax.php',
type: 'POST',
contentType: false,
processData: false,
data: formData,
dataType: 'json',
success: function(json) {
alert(json);
},
error:function(XMLHttpRequest, textStatus, errorThrown) {
alert(XMLHttpRequest.responseText);
}
});

php Action

class Sample_Action_AjaxHogeLoad extends Wataca_ActionClass
{
public function prepare()
{
return null;
}

public function perform()
{
$HogeMgr = $this->backend->getManager('Hoge');
$hoge = $HogeMgr->load();
if (empty($hoge)) {
$this->ae->add("no_hoge", "ほげは空です。");
return 'ajax_error';
}
$this->af->setApp('data', $hoge);
return 'ajax_json';
}
}

php View

class Wataca_View_AjaxJson extends Wataca_AjaxViewClass
{
public function preforward()
{
header('Content-Type: application/json; charset=UTF-8'); // ここポイント
}
}

php template

{json_encode($app.data)} {* tpl 上で JSON へ変換 *}


これに行き着くまではアクションで json 出力して exit() して、バリデートエラーのときどうしよう、今回は割愛、、、みたいな感じだった。こった同僚は php と javascript とそれぞれにレスポンスを扱うクラスを用意してたり。このやりかたも結局アクションで exit() しちゃってんだよね。それって Ethna である必要ある?って。そもそもバリデートエラーなのに success で受け取るのが気持ち悪い。これをなんとかできないか?

新しいプロジェクトを開始したときに、これからは Ajax を多用するだろうということで他のフレームワークも検討しようと思ったんだけど急かされてたのもあって引き続き Ethna を採用。Ajax どうしようってそれだけが不安だったんだけどようやく解決。


ついでに tpl 上で php から javascript に値を渡したいときはこんな感じ。

javascript

var data = {json_encode($app.data)};
// do something...


次ぎは javascript の MVC フレームワークを使ってみたい。それと Ethna とうまく連携させてみたい。

かわのくんとは

Web系IT企業でプログラミングやマネジメントをしています。趣味で音楽を少々。

Youtubeでライブ動画配信中

Ustreamでライブ動画配信中

スマートフォン向けにPCサイトを自動変換(コンバート)する『CONV2SP』 CSS作成支援ツール『CSSツクール』