首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在表单更新中重新加载<p:dataScroller>

在表单更新中重新加载<p:dataScroller>
EN

Stack Overflow用户
提问于 2015-07-03 16:10:29
回答 2查看 1.4K关注 0票数 3

随机的想法:我讨厌他们在dataScroller中编码的“孤独狼”的行为.

我试图在<p:selectOneMenu>上实现一个基于用户选择的筛选器,它将根据选择从<p:dataScroller>中重新加载<p:dataScroller>中显示的内容。

MB (EnglishNumberToWords) (随机串)

代码语言:javascript
复制
import java.util.*;
import se.answers.EnglishNumberToWords;
import java.security.SecureRandom;

@ManagedBean
@ViewScoped
public class bean {
private List<String> itens;
private Integer choice = 1; //initialize;
private LazyDataModel<String> model;
// getter setter

@PostConstruct
public void postConstruct() {
    int count = loadStringsFromElsewhere();
    model = new LazyModelImplmentation(this);
    model.setRowCount(count);
}

public Map<String, Integer> mapChoices() {
    Map<String, Integer> map = new LinkedHashMap<String, Integer>();
    for(int ii=0;ii<5;ii++) {
        map.put(ii, convertLessThanOneThousand(ii));
    }
}

public List<String> getChunk(int first, int pageSize) {
    SecureRandom random = new SecureRandom();
    int listSize = itens.size();
    int added = 0;
    int end = int+pageSize;
    while(end > itens.size(){
        added++; //the real code here is different, I will just randomize.
        int criteria = (random.nextInt(5) + 1);
        if(criteria == choice) { // filters out Strings.
            String ss = criteria + BigInteger(130, random).toString(32)
            itens.add(ss);
        }
    }
    return itens.subList(Math.min(first, itens.size()), Math.min(end, itens.size()));
    }

/**
 *  Get the dataScroller itens from elsewhere, NOT a database.<p>
 *  here we will use only randons.
 */
private int loadStringsFromElsewhere() {
    SecureRandom random = new SecureRandom();
    if(itens == null) {
       itens = new ArrayList<String>();
    }
    for(int ii=0;ii<  (random.nextInt(50) + 100); ii++) {
        int criteria = (random.nextInt(5) + 1);
        String ss = criteria + BigInteger(130, random).toString(32);
        itens.add(ss);
    }
}
}

LazyModelImpl

代码语言:javascript
复制
import java.util.List;
import java.util.Map;

import org.primefaces.model.LazyDataModel;
import org.primefaces.model.SortOrder;

public class LazyModelImplmentation extends LazyDataModel<String> {
    private static final long serialVersionUID = 1L;
    private Bean bean;

public LazyModelImplmentation(Bean bean) {
    this.bean = bean;
}

@Override
    public List<String> load(int first, int pageSize, String sortField,
            SortOrder sortOrder, Map<String, Object> filters) {
        return bean.getChunk(first, pageSize);
    }   
}

JSF

代码语言:javascript
复制
<h:form prependId="false">
   <p:selectOneMenu value="#{bean.choice}">
        <f:selectItems value="#{bean.mapChoices()}" />
        <p:ajax process="@form" update="@form" />
    </p:selectOneMenu> 
    <p:dataScroller id="da_scroller" var="item" 
        value="#{bean.model}" rowIndexVar="index" chunkSize="10" lazy="true">

    <!-- SHOW THE DATA IN THE item -->
        <h:outputText value="#{index}: #{item.toString()}" />
        <hr />

    </p:dataScroller>
</h:form>

但是dataScroller只是忽略了表单更新,并一直显示相同的数据。只有通过延迟模型加载的新数据才会被更新,并与旧数据混合。

如何清理表单更新中的dataScroller,使其只显示新数据(如果返回到第一个数据块,则加分)。

在Tomcat 7和jsf2.2上使用PrimeFaces5.0(但jsf是在标记上)。

EN

回答 2

Stack Overflow用户

发布于 2015-07-07 14:25:38

在修改了<p:dataScroller>的源代码之后,我想出了一个解决方案。没有文档化的方法来更改已经附加的内容,而组件只是附加了更多的内容。

所以我不得不破解我自己的解决方案:

  1. Lie to the <p:dataScroller>
代码语言:javascript
复制
- The component does not work properly if you do not `setRowCount()` on the lazyModel. It only fetches two chunks and then stop.
- Changing the rowCount on the fly also does not have the intended effect. The component keeps its own internal count. [[3](https://stackoverflow.com/a/19409307/1532705)]
- Also as of Primefaces 5.0, setting rowCount to `Integer.MAX_VALUE` causes the dataScroller to halt (client-side) on the fetch of the second chunk. I suspect some _Shlemiel the painter_ [[1](http://www.joelonsoftware.com/articles/fog0000000319.html)] [[2](https://en.wikipedia.org/wiki/Joel_Spolsky#Schlemiel_the_Painter.27s_algorithm)] somewhere.
- So on the init of the LazyDataModel, set a rowCount large enough (but not too large). I set it to 100,000.

  1. 欺骗:我可以控制到dataScroller的内容,因为我在@ManagedBean上构建了块,所以如果我想重新设置列表并从一开始就开始服务,我可以。我将把getChunk()方法的确切实现(请参阅上面问题上的清单)留给读者,但只需自己计算,而不是依赖于LazyDataModel<T>.load()的参数。
  2. 窃听器:清理<p:selectOneMenu>的AJAX调用中已经加载的条目(绑定到onstart,因为在dataScroller更新之前不能确保有一个窗口可以这样做):

票数 3
EN

Stack Overflow用户

发布于 2016-11-06 17:12:24

有一个简单的方法:

只需将数据库放在面板中,然后:

  • 在datascroller中将呈现的属性更改为false。
  • 更新面板
  • 用新数据重新加载datascroller列表
  • 在datascroller中再次将呈现的atribute更改为true。
  • 更新面板

=)

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31210812

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档