通过OmniFaces缓存组件以编程方式缓存PrimeFaces图表

在这篇文章中,您将看到如何结合PrimeFaces和OmniFaces获得可缓存的图表。 为了使事情变得简单,我们将使用PrimeFaces 折线图。 对于这种图表,我们可以在页面中使用<p:chart />标记和一个简单的托管bean。 因此,在页面中我们可以有:

<p:chart id="someChartId" type="line"
         model="#{chartView.lineModel}"
         style="height:300px;width:600px;"/>

ChartView可以编写如下:

@Named
@ViewScoped
public class ChartView implements Serializable {

 private LineChartModel lineModel;

 @PostConstruct
 public void init() {
  createLineModels();
 }

 private void createLineModels() {
  lineModel = initLinearModel();
  lineModel.setTitle("Linear Chart");
  lineModel.setLegendPosition("e");
  lineModel.setZoom(true);
  Axis yAxis = lineModel.getAxis(AxisType.Y);
  yAxis.setMin(0);
  yAxis.setMax(10);
 }

 private LineChartModel initLinearModel() {
  LineChartModel model = new LineChartModel();

  LineChartSeries series1 = new LineChartSeries();
  series1.setLabel("Series 1");

  Random rnd = new Random();

  series1.set(rnd.nextInt(10), rnd.nextInt(10));
  series1.set(rnd.nextInt(10), rnd.nextInt(10));
  series1.set(rnd.nextInt(10), rnd.nextInt(10));
  series1.set(rnd.nextInt(10), rnd.nextInt(10));
  series1.set(rnd.nextInt(10), rnd.nextInt(10));

  LineChartSeries series2 = new LineChartSeries();
  series2.setLabel("Series 2");
  series2.set(rnd.nextInt(10), rnd.nextInt(10));
  series2.set(rnd.nextInt(10), rnd.nextInt(10));
  series2.set(rnd.nextInt(10), rnd.nextInt(10));
  series2.set(rnd.nextInt(10), rnd.nextInt(10));

  model.addSeries(series1);
  model.addSeries(series2);

  return model;
 }

 public LineChartModel getLineModel() {
  return lineModel;
 }
}

此代码将产生一个简单的折线图,如下图:

primfaces线性图样本

现在,让我们假设在应用程序运行期间,该图表会定期更新或重新创建(我们将通过随机序列值和“ Refresh按钮对此进行模拟)。 每次发生这种情况时,我们都会丢失当前图表。 但是,缓存(如保存)某些图表可能很有用,并且有可能稍后在当前会话(对于属于某些用户的图表)/应用程序(对于所有用户通用的图表)中加载它们。

为了完成此任务,我们可以使用OmniFaces 缓存组件。 基本上,此组件在OmniFaces ShowcaseMastering OmniFaces书中都有很好的描述,但主要思想是:

  • Cache组件通过以下方式向JSF页面作者公开
    <o:cache>标记。
  • Cache为“渲染响应”阶段生成的标记实现了服务器端缓存机制。
  • Cache在“渲染响应”阶段执行操作。
  • 缓存的标记存储在OmniFaces生成的密钥下,或者通过可选的<o:cache>密钥属性指示。
  • 可以通过可选的<o:cache>禁用的flag属性禁用每个请求的<o:cache>
  • 可以通过<o:cache> reset flag属性来重新缓存已缓存的条目。
  • 默认情况下,缓存的数据存储在会话范围内(也支持应用程序范围)。

例如,从JSF页面作者的角度来看,我们可以表明我们想在键foo下重新缓存一块标记,如下所示:

<o:cache id="cacheId" key="foo" disabled="false" reset="true">      
 ... // the markup produced for this snippet of code will be cached
</o:cache>

显然,在此示例中, disabled属性可以跳过,因为那是其隐式值。 如果还跳过了key ,则OmniFaces将生成一个。 如果跳过了reset ,则不会重新缓存标记。

既然我们要必须决定哪些图表缓存和负载的可能性/删除某个图表从缓存中,我们不能简单地做只有这个:

<o:cache id="cacheId">      
 <p:chart id="someChartId" type="line"
          model="#{chartView.lineModel}"
          style="height:300px;width:600px;"/>                   
</o:cache>

基本上,这将缓存第一个图表,并且在每次回发时,将从缓存中为该图表提供服务。

因此,一种快速的方法将包括以编程方式处理<o:cache>属性。 就像我在上面说的, Cache在“渲染响应”阶段采取行动。 这意味着我们可以从我们的控制
ChartView bean在实际发生Cache之前是Cache组件。 此实现的核心将包含以下private方法,该方法允许我们以编程方式配置Cache组件:

private void configureCache(String key, boolean disabled, boolean reset) {
 Cache cache = Components.findComponent("cacheId");
 cache.setDisabled(disabled);
 cache.setReset(reset);
 cache.setKey(key);
}

现在,我们将添加一对一的控制缓存所需的UI。 首先,我们添加一个标记为“
刷新。 实际上,每次我们按下此按钮时,都会生成一个新图表(新数据)。 这是用于模拟图表更新。

<h:commandButton action="#{chartView.redrawAction()}" value="Refresh"/>

redrawAction()确保新图表不被缓存,因此缓存被禁用并且密钥不相关:

public void redrawAction() {
 configureCache("none", true, false);
 createLineModels();
}

此外,我们添加了一个名为Save的按钮。 按下此按钮时,当前图表将缓存在key_ random-number类型的键下(在实际情况下,您可能希望允许用户提供该键作为图表标题)。 该key将在代表已保存图表的列表中向用户公开:

<h:commandButton action="#{chartView.saveChart()}" value="Save"/>

saveChart()方法启用缓存并生成一个新密钥。 密钥存储在列表中:

private List<String> keys;
...
public void saveChart() {
 String key = "key_" + new Random().nextInt(1000);
 configureCache(key, false, true);
 keys.add(key);
}

接下来,我们列出缓存的键和一个标记为Load的按钮。 用户可以选择一个键,然后单击
加载按钮以加载缓存的图表:

<h:selectOneMenu value="#{chartView.selected}">
 <f:selectItem itemLabel="Select a chart ..." noSelectionOption="true"/>
 <f:selectItems value="#{chartView.keys}" var="t" itemLabel="#{t}" itemValue="#{t}"/>
</h:selectOneMenu>
   
<h:commandButton value="Load Chart" action="#{chartView.loadChart()}"
                 disabled="#{chartView.keys.size() eq 0}"/>

loadChart()是:

public void loadChart() {
 if (selected != null) {
     configureCache(selected, false, false);
 }
}

最后,我们添加一个标记为Delete的按钮,该按钮将从缓存中删除所选图表:

<h:commandButton value="Delete Chart" action="#{chartView.deleteChart()}"
                 disabled="#{chartView.keys.size() eq 0}"/> |

并且, deleteChart()是:

public void deleteChart() {
 if (selected != null) {
     CacheFactory.getCache(Faces.getContext(), "session").remove(selected);
     keys.remove(selected);
     configureCache("none", true, false);           
     resetLineModels();
 }
}

private void resetLineModels(){       
 lineModel.getSeries().clear();
}

注意这里,我们如何使用CacheFactory通过密钥从缓存中删除条目。

这是一个提示性屏幕截图:

Primefaces和Omnifaces图表

翻译自: https://www.javacodegeeks.com/2015/11/programmatically-caching-primefaces-charts-via-omnifaces-cache-component.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值