SubmitComponentを改良する

さて、問題解決にはどうしたら良いかと言うことです。

SubmitComponentはpageBeginRenderメソッドでsubmitMessage変数を初期化します。この初期化自体はMessageオブジェクトのインスタンスを作るだけです。

SubmitComponent.java(抜粋)

	public void pageBeginRender(PageEvent arg0) {
		Message mes = new Message();
		setSubmitMessage(mes);
	}

SubmitComponentは新規にメッセージを投稿する時にも、返信メッセージを投稿する時にも使います。
今のままではバインドしたメッセージが表示されない可能性があります。

この辺が一番Tapestry的に一番謎な部分だったのです。
WebObjectsでも同様な問題がたまに起きます。
セッションを立てれば簡単に出来ますが、掲示板でセッションを立てたくない・・
バインドするとなるとの記述を.jwcに加える必要がありますが、どうもを同じ変数に向かって定義できないようなんです・・・

いろいろ調べて最終的に落ち着いた方法と言うのが以下です。
を使ったsubmitMessage変数の定義はやめて、通常どおりgetter、setterを自前で書く事にします。
また、pageBeginRenderメソッドは実装する必要がなくなったので、削除します。そのかわりに、getterに細工して、submitMessageが外部からバインドされていない場合(新規メッセージ投稿時)、かつてpageBeginRender内で行っていたことと同じことを行うという処理に変更します。

SubmitComponent.java

package bbs.view;

import java.util.Date;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.log4j.Level;
import org.apache.tapestry.BaseComponent;
import org.apache.tapestry.IRequestCycle;
import org.objectstyle.cayenne.access.DataContext;
import org.objectstyle.cayenne.conf.Configuration;

import bbs.data.Message;

/**
 * 投稿コンポーネント
 * 
 * @author toolkit
 * @version $Revision$
 */
public class SubmitComponent extends BaseComponent {
	private static final Log log = LogFactory.getLog(SubmitComponent.class);
	private Message submitMessage;

	public Message getSubmitMessage() {
		if (submitMessage == null) {
			setSubmitMessage(new Message());
		}
		return this.submitMessage;
	}

	public void setSubmitMessage(Message submitMessage) {
		this.submitMessage = submitMessage;
	}

	public void submitAction(IRequestCycle rc) {
		Message mes = getSubmitMessage();
		Date now = new Date();
		mes.setSubmitDate(now);
		mes.setModificationDate(now);

		DataContext context = Configuration.getSharedConfiguration().getDomain().createDataContext();
		context.registerNewObject(mes);
		context.commitChanges(Level.WARN);
		log.info("submitMessage = " + mes);
		TestPage nextPage = (TestPage) rc.getPage("TestPage");
		rc.activate(nextPage);
	}

}

同時に、.jwcファイルも修正します。

SubmitComponent.jwc

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE component-specification PUBLIC
  "-//Apache Software Foundation//Tapestry Specification 3.0//EN"
  "http://jakarta.apache.org/tapestry/dtd/Tapestry_3_0.dtd">

<component-specification class="bbs.view.SubmitComponent"
    allow-body="no"
    allow-informal-parameters="no">
	
	<parameter name="submitMessage" type="bbs.data.Message" direction="in"/>

	<component id="subject" type="TextField">
		<binding name="value" expression="submitMessage.subject"/>
	</component>
	<component id="userName" type="TextField">
		<binding name="value" expression="submitMessage.userName"/>
	</component>
	<component id="userPass" type="TextField">
		<binding name="value" expression="submitMessage.userPass"/>
		<binding name="hidden" expression="true"/>
	</component>
	<component id="mail" type="TextField">
		<binding name="value" expression="submitMessage.mail"/>
	</component>
	<component id="url" type="TextField">
		<binding name="value" expression="submitMessage.url"/>
	</component>
	<component id="content" type="TextArea">
		<binding name="value" expression="submitMessage.content"/>
	</component>
	
	<component id="submitButton" type="Submit">
		<binding name="listener" expression="listeners.submitAction"/>
	</component>    
</component-specification>

のrequired属性は省略しています。新規投稿時はバインドする必要が無いからです。


ちょっと難儀しましたが、なんとか返信ページも作る事が出来ました。(クリックで拡大)