ard.end}"/>
</h:panelGrid>
</h:form>
</ui:composition>
JSF 2简介:JSF向导(7)
时间:2010-10-26 IBM David Geary
当用户单击 Next 或 Previous 按钮时,JSF 就会向服务器进行一次 Ajax 调用,并且当此 Ajax 调用返回时,JSF 就会更新问题、问题的选择(单选按钮)以及按钮本身。
Finish 按钮不是一个 Ajax 按钮,因为单击它会导航到 done 页面。
请注意清单 7 和 8 中对 wizard bean 有很多引用。该 bean 实际上是这个测验向导的一个控制器。我在本文结束之前来介绍一下这个 bean。
CDI: Dependency injection and conversations
CDI 可被描述为打了激素的 JSF 托管 beans。作为 Java EE 6 的一个组件,CDI 可以说是在 Spring 内酝酿许久的一些概念的标准化,比如依赖注入和拦截器。实际上,CDI 和 Spring 3 有很多类似的特性。
CDI 让您能够通过松散耦合(loose coupling)和强类型化(strong typing)为关注点解除耦合。这样一来,您就得以从日常的 Java 编程的辛劳中解放出来,比如实例化对象和控制对象的生命期。
从 JSF 的角度,CDI 的一个特别吸引人之处是 conversation 作用域。conversation 作用域是 Seam 最早提出来的,指的是一个生命期可通过编程方式控制的作用域,它让您能够从请求和会话之间的全有或没有的两难中逃离出来。
此向导对 CDI 的所有使用都位于 Wizard bean 内,如清单 9 所示:
清单 9. Wizard bean
package com.clarity;
import java.io.Serializable;
import javax.enterprise.context.Conversation;
import javax.enterprise.context.ConversationScoped;
import javax.enterprise.inject.Produces;
import javax.faces.event.ActionEvent;
import javax.inject.Inject;
import javax.inject.Named;
@Named()
@ConversationScoped()
public class Wizard implements Serializable {
private static final long serialVersionUID = 1L;
private Questions questions = new Questions();
private int cursor = 0;
@Inject
private Conversation conversation;
@Produces @Named
public Question[] getQuestions() {
return questions.getQuestions();
}
public void nextButtonClicked(ActionEvent e) {
incrementCursor();
}
public void previousButtonClicked(ActionEvent e) {
decrementCursor();
}
public void incrementCursor() { ++cursor; }
public void decrementCursor() { --cursor; }
public int getCursor() { return cursor; }
public void resetCursor() { cursor = 0; }
public boolean getNextButtonEnabled() {
return cursor != questions.size() - 1 &&
(questions.getQuestions())[cursor].isAnswered();
}
public boolean getPreviousButtonEnabled() {
return cursor > 0;
}
public boolean getFinishButtonEnabled() {
return cursor == questions.size() - 1 &&
(questions.getQuestions())[cursor].isAnswered();
}
public String start() {
conversation.begin();
return "quizWizard/wizard";
}
public String end() {
conversation.end();
return "/done";
}
private void setCurrentQuestionUnanswered() {
Question currentQuestion = (questions.getQuestions())[
|