Mojarra 2.1如何檢測validator中的valueChange事件?
我需要爲h:inputText
寫一個驗證器,它只有在該輸入值改變時纔會執行一些邏輯。即
public class MyValidator implements Validator{
public void validate(FacesContext context,
UIComponent component,
Object value) throws ValidatorException;
if(valueChanged(UIComponent component)){ //The method checks if the value's changed
//do some piece of logic
}
return;
}
}
我挖成UIInput
的排隊事件和發現這一點:
validateValue(context, newValue);
// If our value is valid, store the new value, erase the
// "submitted" value, and emit a ValueChangeEvent if appropriate
if (isValid()) {
Object previous = getValue();
setValue(newValue);
setSubmittedValue(null);
if (compareValues(previous, newValue)) {
queueEvent(new ValueChangeEvent(this, previous, newValue));
}
}
這段代碼是從所述方法中,通過驗證階段回調執行。首先想到的是查詢處理請求期間發生的所有事件。該方法queueEvent(FacesEvent)
被實現如下:
public void queueEvent(FacesEvent event) {
if (event == null) {
throw new NullPointerException();
}
UIComponent parent = getParent();
if (parent == null) {
throw new IllegalStateException();
} else {
parent.queueEvent(event);
}
}
因此每一個這樣的invokation將在UIViewRoot.queueEvent(FacesEvent)
最終成爲被實現:
public void queueEvent(FacesEvent event) {
if (event == null) {
throw new NullPointerException();
}
// We are a UIViewRoot, so no need to check for the ISE
if (events == null) {
int len = PhaseId.VALUES.size();
List<List<FacesEvent>> events = new ArrayList<List<FacesEvent>>(len);
for (int i = 0; i < len; i++) {
events.add(new ArrayList<FacesEvent>(5));
}
this.events = events;
}
events.get(event.getPhaseId().getOrdinal()).add(event);
}
這意味着,所有事件實際上是作爲一個List<List<FacesEvent>>
每個階段期間存儲。但List<List<FacesEvent>> events
是一個私人領域,所以它不可能直接訪問它。
另一件事是在quingEvent
之前正在進行實際驗證,因此實施valueChangeListener
似乎也不太有用。
問題:是否有可能在一個自然的方式以實現在JSF
這樣的驗證?
再澄清一點:'getValue()'方法直接從解碼的'ViewState'中獲取值? –
這部分基本上回答在http://stackoverflow.com/questions/31955955/understanding-jsf-components-class-lifetime/31958332#31958332所以,只有當本地值設置(即以前提交的值沒有使它更新模型值階段),它基本上從視圖狀態中抓取。 – BalusC