Sencha列表分页插件

5

我正在尝试使用sencha touch的listpaging插件。但是几乎没有关于如何使用它的好(或坏)文档,我很困惑。

当我在我的列表中激活插件时

this.myList = new Ext.List({
  store: this.myStore,
  plugins: [{
    ptype: 'listpaging',
    autoPaging: false
  }],
  itemTpl: '...'
});

列表末尾添加了“加载更多”文本和加载图像。

但是我不知道如何配置我的商店以启用此插件以加载更多数据。

App.regStore('MyStore', {
 model: 'myModel',
 proxy: {
    type: 'ajax',
    url: 'http://mydomain.com/json?howmany=10&page=1',
    reader: {
        type: 'json',
        root: 'results'
    }
  }
});

App.stores.myStore = Ext.StoreMgr.get('MyStore');

我该如何配置我的商店,使得当我点击“加载更多”时,商店会自动将第二页内容添加到列表中?

5个回答

4

我在SenchaTouch 2中使用了ListPaging插件也遇到了类似的问题,并成功解决了数据集结束时“加载更多”消息的行为。

这基于John Gordon提供的内容(关于指定pageSizeclearOnPageLoad配置选项),因为这些属性在Senchatouch 2中似乎是相同的。我没有详细查看SenchaTouch 1.x。在SenchaTouch 2中,所有配置选项都必须在一个config属性中定义:

Ext.define('MessagingApp.store.MessageThreads', {
    extend  : 'Ext.data.Store',
    requires: ['MessagingApp.model.MessageThread'],

    config:
    {
        model: 'MessagingApp.model.MessageThread',

        autoLoad: false,
        clearOnPageLoad: false,  // This is true by default
        pageSize: 10,            // This needs to be set for paging

        proxy: {
            type: 'jsonp',
            pageParam: 'currentPage',
            limitParam: 'pageSize',
            url: APIURL + '/message-app-service/GetMessageThreads',
            reader: {
                type: 'json',
                rootProperty: 'Data'
            }
        }
    }
});

在视图中,我们可以指定插件并覆盖“加载更多”和“没有更多记录”的消息:
{
    xtype:'dataview',
    store:'MessageThreads',
    id:'threadList',
    itemTpl:Ext.create('Ext.XTemplate',
        '<!-- template markup goes here -->',
        {
            //custom helper functions here
        }
    ),
    plugins:[
        {
            xclass:'Ext.plugin.ListPaging',
            autoPaging: true,

            // These override the text; use CSS for styling
            loadMoreText: 'Loading...',
            noMoreRecordsText: 'All messages loaded'
        }
    ]
}

问题在于,尽管我们的Web服务返回了特定页面的记录数组,但没有总计数属性,这是插件确定所有记录已加载的必要条件。因此,现有问题是,“加载更多”消息将一直存在(接受解决方案中的问题#1)。因此,在我们控制器的init函数中,我们必须为存储库上的load事件附加事件处理程序,以便在接收到新数据页面时进行钩取:
Ext.define('MessagingApp.controller.Messages',
{
    extend: 'Ext.app.Controller',

    config:
    {
        views: [
            'MessageThreads',
            // Other views referenced by this controller
        ],

        stores: [
            'MessageThreads'
        ],

        refs:
        {
            // References to UI elements by selector...
        }
    },

    init: function() {
        // Other internal initialisation...

        this.control(
        {
            // Selector-object pairs...
        });

        // Provide a means to intercept loads of each page of records
        var threadStore = Ext.getStore('MessageThreads');
        threadStore.addBeforeListener('load', this.checkForThreadListEnd, this);
    },

    // Remaining controller functions...

});

在处理程序中,当返回的记录数小于页面大小时,我们会意识到已经到达数据集的末尾。如果总记录数是页面大小的倍数,则最后一页将有一个空数组。一旦确定了数据集的末尾,我们就会更新存储的totalCount配置属性:

checkForThreadListEnd: function(store, records, isSuccessful) {
    var pageSize = store.getPageSize();
    var pageIndex = store.currentPage - 1;    // Page numbers start at 1

    if(isSuccessful && records.length < pageSize)
    {
        //Set count to disable 'loading' message
        var totalRecords = pageIndex * pageSize + records.length;
        store.setTotalCount(totalRecords);
    }
    else
        store.setTotalCount(null);
},

// Other controller functions...

因为这是一个“before”事件处理程序,所以在插件决定是否显示“加载更多”或“没有更多记录”消息之前,此属性将至关重要地更新。不幸的是,框架并没有提供隐藏“没有更多记录”消息的方法,因此必须通过CSS来完成。
希望这可以帮到你。

感谢d_mcg的解决方案。 还有一个问题: “没有更多记录”链接仍然可以点击,并且在单击后向服务器发送请求。您如何解决这个问题?非常感谢 :) - Bogie
不客气 :-) 我还没有找到一个简单的方法来禁用那个按钮,主要是因为SenchaTouch只提供了在任一状态下设置该按钮文本的手段(这是通过“私有”的loadTpl配置属性中的XTemplate应用的)。您可以尝试一些魔法来拦截此按钮的点击事件并返回false(取消事件),或者使用时髦的CSS选择器来隐藏其“没有更多记录”的状态下的按钮。您可以在docs.sencha.com上查看Sencha如何实现它的内部机制。 - d_mcg
忘了说 - 您可以将鼠标悬停在绿色标题上(即类名),以显示该类的“查看源代码...”链接。我发现这对于弄清文档没有提到的一些额外细节非常有帮助。 - d_mcg
嗨@d_mcg,我遇到了同样的问题,你能否请看一下这篇文章?http://stackoverflow.com/questions/29079669/sencha-list-paging-plugin-doesn%C2%B4t-work-properly - inane

2

我也遇到了找不到好的文档的问题,但是我至少可以回答你的问题。如果你想要不清除已经加载的内容,你需要向你的存储器中添加pageSizeclearOnPageLoad。这是我的代码:

Ext.regStore('publicresources', {

model: 'PublicResource',
autoLoad:false,
remoteFilter:true,
sortOnFilter:true,
    pageSize: 15,
    clearOnPageLoad: false, 
sorters: [
    {
        property : 'distance',
        direction: 'ASC'
    }
]

});

我正在研究的主要问题:

  1. 如何在没有更多记录需要加载时关闭“更多”元素;
  2. 如何检测是否有更多记录需要加载,并将该检测代码放在哪里;
  3. 如何让列表停留在用户所在的位置。每次加载后都会跳回列表的第一项。

祝你好运!


谢谢您的回答,如果有任何其他问题,请告诉我。 - keune
我未完成任务清单中的第三项是我的代码问题。我有一段代码,会在数据刷新时强制将用户带回列表顶部,以避免使用sencha touch的列表组件时出现另一个渲染错误。当替换列表的数据少于原来的数据时,该bug会发生,导致列表渲染不正确。 - John Gordon
2
你是否已经找到了解决方案来解决你的第一个问题:“当没有更多记录需要加载时如何关闭‘更多’元素”? - CrocHunter

0

0
关于“加载更多 vs. 没有更多记录”消息的问题 -
如果您正在编写自定义代理(例如这里的 使用PhoneGap的Sencha Touch MVC应用程序),则可以在返回的操作中设置总记录数。
如果尚未知道总记录数,可以执行以下操作:
1)如果您返回请求的记录限制,请将总记录数设置为大于存储现在将保存的记录的记录数的值。
2)如果返回的记录数小于请求的记录限制,请将总记录数设置为1(以强制显示“没有更多记录”的消息)。
    //return model instances in a result set
    operation.resultSet = new Ext.data.ResultSet({
        records: contacts,
        //total  : contacts.length,
        total  : contacts.length === operation._limit ? (operation._limit * operation._page +1) : 1,
        loaded : true
    });
    //announce success
    operation.setSuccessful();
    operation.setCompleted();
    //finish with callback
    if (typeof callback == "function") {
        callback.call(scope || thisProxy, operation);
    }

-1

只是想补充一下我的解决办法...

如果您的服务器返回一个totalCount,并且您想要设置它,您可以在阅读器中使用totalProperty。

reader: {
            type: 'json',
            rootProperty: 'results',
            totalProperty: 'resultCount'
        }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接