3

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


我正在尝试根据用户选择实现一个过滤器,该过滤器将根据选择<p:selectOneMenu>重新加载<p:dataScroller>ManagedBean 中显示的内容。

MB ( EnglishNumberToWords ) (随机字符串)

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

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

<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 上使用 Primefaces 5.0(但 jsf 在标签上)。

4

2 回答 2

3

在摆弄了源代码之后,<p:dataScroller>我没有找到解决方案。没有记录的方法可以更改已附加的内容,并且该组件只是附加了更多内容。

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

  1. 撒谎<p:dataScroller>:_

    • setRowCount()如果您不在lazyModel 上,该组件将无法正常工作。它只获取两个块然后停止。
    • 动态更改 rowCount 也没有预期的效果。组件保持自己的内部计数。[ 3 ]
    • 同样从 Primefaces 5.0 开始,将 rowCount 设置为Integer.MAX_VALUE会导致 dataScroller 在获取第二个块时停止(客户端)。我怀疑某处有画家[ 1 ] [ 2 ] 的 Shlemiel。
    • 所以在 LazyDataModel 的 init 上,设置一个足够大的 rowCount(但不要太大)。我将其设置为 100,000。
  2. 作弊:我可以控制 dataScroller 的内容,因为我在 上构建块@ManagedBean,所以如果我想重置列表并从头开始服务,我可以。我将把getChunk()方法的确切实现(参见上面的问题清单)留给读者,但只保留你自己的计数,而不是依赖 LazyDataModel<T>.load().

  3. 窃取:清除 (bind to the onstart) 的 AJAX 调用中已加载的条目<p:selectOneMenu>,因为在 dataScroller 更新自身之前,您不能确保有一个窗口来执行此操作:
<p:selectOneMenu value="#{bean.choice}">
    <f:selectItems value="#{bean.mapChoices()}" />
    <p:ajax process="@form" update="@form"  onstart="cleanScroller()" />
</p:selectOneMenu>
function cleanScroller() {
    $('li.ui-datascroller-item').remove();
}
于 2015-07-07T14:25:38.897 回答
0

有一个简单的方法:
只需将 datascroller 放在面板中,然后:

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

= )

于 2016-11-06T17:12:24.403 回答