0

我正在尝试在 jQuery Waypoint 和 Masonry API 的帮助下使用 Primefaces 来实现无限滚动。

这是我到目前为止所拥有的:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://xmlns.jcp.org/jsf/html" xmlns:f="http://xmlns.jcp.org/jsf/core"
    xmlns:ui="http://xmlns.jcp.org/jsf/facelets" xmlns:p="http://primefaces.org/ui" xmlns:pe="http://primefaces.org/ui/extensions">
<f:view>
    <h:head>
        <h:outputScript library="primefaces" name="jquery/jquery.js" />
        <h:outputScript name="js/global.js"/>
        <h:outputScript name="js/masonry.pkgd.js"/>
        <h:outputScript name="js/imagesloaded.pkgd.js"/>
        <h:outputStylesheet name="css/global.css" />                
        <title>Gallery</title>      
    </h:head>
    <h:body>
        <h:form prependId="false">      
            <h:panelGroup id="galleryPanel" layout="block">
                <p:outputPanel autoUpdate="true">
                    <h:panelGroup layout="block" styleClass="galleryContainer">
                        <ui:repeat id="gallery" value="#{galleryController.images}"  var="image">
                            <h:panelGroup layout="block" styleClass="item">
                                <h:graphicImage library="images" name="demo/#{image}.jpg" />
                            </h:panelGroup>                 
                        </ui:repeat>
                    </h:panelGroup>                                     
                </p:outputPanel>                
                <pe:waypoint id="waypoint" widgetVar="waypointWidget" offset="function(){return $.waypoints('viewportHeight') - $(this).outerHeight()}">
                    <pe:javascript event="reached" execute="handleLoadStart(ext);"/>  
                </pe:waypoint>
                <h:outputScript target="body">
                    var layout = function(){
                        var container = $('.galleryContainer');
                        $(container).imagesLoaded(function(){
                            $(container).masonry({
                                itemSelector : '.item',
                                columnWidth : 240
                            });
                        });
                    };

                    var handleLoadStart = function(ext) {
                        if (ext.direction == "down") { 
                            PF('waypointWidget').remove();                          
                            moreMedia();
                        }
                    };

                    var handleLoadStop = function(){
                        layout();
                        PF('waypointWidget').register();                         
                    };                  

                    $(document).ready(function(){
                        layout();
                    });
                </h:outputScript>               
                <p:remoteCommand name="moreMedia" update="gallery" actionListener="#{galleryController.loadMore}" oncomplete="handleLoadStop()"/>
            </h:panelGroup>
        </h:form>
    </h:body>
</f:view>
</html>

托管 Bean 是:

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.IntStream;

import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.event.ActionEvent;

@ManagedBean(name="galleryController")
@ViewScoped
public class GalleryController implements Serializable {

    private static final long serialVersionUID = 563439107531288284L;

    private List<String> images;

    @PostConstruct
    public void initialize() {
        images = new ArrayList<>();     
        IntStream.range(1, 16).forEach(i->images.add(new String("image" + i)));     
    }

    public void loadMore(ActionEvent event){
        IntStream.range(1, 16).forEach(i->images.add(new String("image" + i))); 
    }

    public List<String> getImages() {
        return images;
    }

    public void setImages(List<String> images) {
        this.images = images;
    }    
}

它正在部分工作,因为它有问题。

主要问题是,当我将新图像添加到现有图像列表中时,它ui:repeat会完全渲染。我不想这样做。因为通过这种方式,现有图像也会被加载。现代浏览器如 FF 或 Chome 缓存图像,所以这对他们来说不是问题,但在像 IE 这样的浏览器中,我可以在网络控制台中看到它正在发送 GET 来获取这些图像。从性能角度来看,不应获取已加载的图像,而应仅获取新添加的图像。

但我不知道如何在 JSF 中做到这一点!

同样作为副作用,砌体没有按预期工作。每次触发该方法onComplete时,滚动条都会设置到顶部。从功能的角度来看,它应该停留在 Waypoint 触发下一次加载的位置。p:remoteCommandlayout()

任何建议都会非常有帮助。

4

3 回答 3

0

顺便说一句,PrimeFaces Extensions 有基于 Masonry 的 pe:fluidGrid。查看展示http://primeext.mooo.com:8080/primeext-showcase/views/fluidGrid.jsf

于 2014-01-12T10:00:49.910 回答
0

初始加载后不再更新 ui:repeat 。使用临时数据存储,例如 h:inputHidden 来保存托管返回和格式化的数据,然后使用 JavaScript 将数据从 h:inputHidden 移动到 Masonry。在 Masonry 中使用以下内容附加数据:

$container.masonry( "appended", html, true );    

其中 html 是 h:inputHidden 的数据

如果您愿意,可以访问下面的博客了解详细信息。它不使用 PrimeFaces 或 WayPoints,但 Masonry 的更新方式与想要做的类似。

http://kahimyang.info/kauswagan/code-blogs/1699/how-to-use-and-append-data-to-masonry-in-responsive-jquerymobile-with-jsf-2-and-ajax

于 2015-03-02T19:53:19.537 回答
0

假设您需要一个无限列表

<ul>
   <li>item 1</li>
   <li>item 2</li>
   <li>...</li>
</ul>

这个想法是创建一个名为 list.xhml 的复合组件,例如具有属性索引。例如,该组件可以加载包含 10 个元素的页面。滚动时,使用 JQuery ajax 加载该组件并将其添加到 dom。

于 2020-10-27T14:16:54.780 回答