2015-10-17 44 views
0

正如我繼續我的JSF項目我已經達到了一個點,我需要一些幫助,以進一步讓我的工作。實現Observer模式與@Dependent

首先,我的整個項目可在此鏈接:https://github.com/vasigorc/rimmaproject它編譯和運行。

兩個詞,我已經採取預約的頁面。到目前爲止,約會的唯一領域是日期。它通過primefaces日曆組件輸入。約會會話約會bean實現Observable接口(Observer設計模式的一部分)。每當日期值發生變化時,通知觀察者。觀察者是從屬的 bean,該bean調用REST客戶端以獲取所選日期的天氣預報的對象表示。一旦日期被選定最終用戶點擊提交天氣預報應該出現在同一個頁面的右側部分。

測試完成:我有單元測試了所有的部分獲取方法,以及Observer和Observable實現之間的集成。但是當我運行該應用程序時,更改日期並點擊'提交'日期不會出現。

我找不到一個計算器票這將說明了同樣的問題,但我發現它描述瞭如何實現在JSF不同的設計模式的IBM文章。他們的建議是使用事件監聽器方法。在設計我的應用程序之前,我想要徵求您的建議,試圖找到我的應用程序現在構建的缺陷。

採取預約代碼 前端 頁:

<div class="col-md-4"> 
     <h:form>  
      <h:panelGrid columns="2"> 
       <span>#{copy.pickadate}</span> 
       <p:calendar id="calendar" value="#{appointmentFormBean.selectedDate}" locale="fr" 
          mindate="today" maxdate="today+90" mode="popup" 
          pattern="yyyy-MM-dd">     
       </p:calendar> 
       <input id="requestButton" type="button" value="#{copy.submitButton}"> 
        <f:ajax event="click" execute="calendar" render="out weatherwidget"></f:ajax> 
       </input>     
      </h:panelGrid> 
     </h:form>  
    </div> 
    <div class="col-md-4 col-md-offset-4"> 
     <ui:include id="weatherwidget" src="restservice/weatherWidget.xhtml"/> 
    </div> 
    <div><h:outputText id="out" value="#{appointmentFormBean.selectedDate}"></h:outputText></div> 

'天氣小工具'

<ui:composition>   
     <h:panelGrid columns="3" class="table table-bordered"> 
      <h:outputText rendered="#{appointmentFormBean.datePickerActivated}">#{forecastBeanTwo.forecast.day}</h:outputText> 
     </h:panelGrid>    
</ui:composition> 

預約支持bean的簽名:

@Named(value = "appointmentFormBean") 
@SessionScoped 
public class AppointmentFormBean implements Serializable, Observed 

負責調用觀察員

public void setSelectedDate(Date selectedDate) { 
    this.selectedDate = selectedDate; 
    notifyVGObservers(); 
    setDatePickerActivated(true); 
} 
@Override 
public void notifyVGObservers() { 
    observers.stream().map((observer1) -> (VGObserver) observer1).forEach((observer) -> { 
     observer.update(selectedDate); 
    }); 
} 

的 '觀察員' Bean的簽名和託管財產申報方法:

@ManagedBean 
@Dependent 
public class WeatherForecastBean implements Serializable, VGObserver 
@ManagedProperty(value = "#{appointmentFormBean}") 
private AppointmentFormBean formBean; 

可觀察的注入點..

//point of IoC 
public void setFormBean(AppointmentFormBean formBean) { 
    this.formBean = formBean; 
    formBean.registerVGObserver(this); 
} 

最後,更新方法:

Override 
public void update(Date selectedDate) { 
    /* 
     get the 15 days from today date object 
     and check whether the client requested day is not 
     after it. 
    */ 
    Calendar cal = Calendar.getInstance(); 
    cal.add(Calendar.DATE, +15); 
    if (selectedDate.after(cal.getTime())) { 
     /* 
      So, if the selected date is after today+15 days 
      then we will tell the client that we cannot grab a weathe for him 
      i.e. DailyForecast = UnavailableForecast.class 
     */ 
     setForecast(new UnavailableForecast()); 
    }else{ 
     /* 
      Now that we know that the selected date is within the range 
      of available forecasts, we need to extract the requested day 
      forecast (represented by a Time object) 
      from the total of 16 available days 
     */ 
     java.sql.Date sqlDate = utilToSql(selectedDate); 
     Time requestedTime = findGoodTime(dwr.getDays(), 
       (Time t)->sqlDate.toString().equals(t.getDay())); 
     setForecast(new TimeAdapter(requestedTime)); 
    }   
} 

這不是一個簡單的問題。正如我所說,完整的代碼在github上可用,但也歡迎您提出任何問題。任何建議都會有很大的幫助。

+0

在HTTP中,用戶必須發送請求才能獲得響應。 – BalusC

+0

謝謝你的回答。我想在用戶點擊ID爲「requestButton」的按鈕時發送部分(異步)請求。 – vasigorc

回答

0

我放棄了我的舊設計,因爲我需要繼續推進這個項目。我放棄了觀察員觀察的對象關係,並正在採取提到的IBM之前文章所建議的路徑:自動對時

Observer模式 Observer模式的目的是通知所有依賴的對象(或觀察員)狀態在主題變化。 JSF框架在UI組件中實現Observer模式。 JSF技術有兩種內置事件:ActionEvent和ValueChangedEvent。 ActionEvent在確定用戶界面組件(如按鈕)的激活時非常有用。當用戶點擊按鈕時,JSF實現會通知添加到按鈕的一個或多個操作偵聽器。該按鈕被激活或按鈕(主體)的狀態改變。所有聽衆(或觀察者)都會收到添加到按鈕的主題狀態變化的通知。同樣,當輸入UI組件中的值更改時,JSF實現將通知ValueChangeListeners。

來源:http://www.ibm.com/developerworks/library/wa-dsgnpatjsf/

這些是我所做的更改。

在前端我添加了一個PrimeFaces 事件監聽

<p:calendar id="calendar" value="#{appointmentFormBean.selectedDate}" locale="fr" 
          mindate="today" maxdate="today+90" mode="popup" 
          pattern="yyyy-MM-dd">  
        <p:ajax event="dateSelect" listener="#{forecastBeanTwo.handleDateSelect}"/> 
       </p:calendar> 

在後端我已經改變了update()方法與handleDateSelect()方法:

public void handleDateSelect(SelectEvent event){ 
    /* 
     get the 15 days from today date object 
     and check whether the client requested day is not 
     after it. 
    */ 
    Date selectedDate= (Date)event.getObject(); 
    Calendar cal = Calendar.getInstance(); 
    cal.add(Calendar.DATE, +15); 
    if (selectedDate.after(cal.getTime())) { 
     /* 
      So, if the selected date is after today+15 days 
      then we will tell the client that we cannot grab a weathe for him 
      i.e. DailyForecast = UnavailableForecast.class 
     */ 
     setForecast(new UnavailableForecast()); 
    }else{ 
     /* 
      Now that we know that the selected date is within the range 
      of available forecasts, we need to extract the requested day 
      forecast (represented by a Time object) 
      from the total of 16 available days 
     */ 
     java.sql.Date sqlDate = utilToSql(selectedDate); 
     Time requestedTime = findGoodTime(dwr.getDays(), 
       (Time t)->sqlDate.toString().equals(t.getDay())); 
     setForecast(new TimeAdapter(requestedTime)); 
    } 
    setBeanActivated(true); 
} 

儘管如此,所有的工作都讓我感到沮喪,因爲這個設計看起來像一個解決方法。