2015-10-17 90 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); 
} 

尽管如此,所有的工作都让我感到沮丧,因为这个设计看起来像一个解决方法。