将onLoad Listener添加到Sencha触摸列表



我想在加载数据后对List执行选择操作,因为根据我收到的数据,我必须在该列表中选择一个单元格,还需要在此基础上更新详细信息视图。

Ext.define('WaxiApp.view.ProductViews.ProductList', {
extend: 'Ext.Container',
alias: "widget.ProductList",
requires: [
'Ext.Img',
],
config: {
layout: Ext.os.deviceType == 'Phone' ? 'fit' : {
type: 'hbox',
pack:'strech'
},
cls: 'product-list',
items: [{
xtype: 'list',
id:'product-list-view',
width: '100%',
height:'100%',
store: 'ProductsList',
infinite: true,
plugins: 'sortablelist',
itemCls: 'productList',
itemId:"product-item",
itemTpl: new Ext.XTemplate(
'<div class="list-content-div ',
'<tpl if="this.needSortable(isNeedInventry)">',
Ext.baseCSSPrefix + 'list-sortablehandle',
'</tpl>',
'">',
'<b>{UpcCode} {Name}</b>',
'<tpl if="isActive">',
'</div>',
'</tpl>',
{
// XTemplate configuration:
compiled: true,
// member functions:
needSortable: function (isneedInventry) {
return !isneedInventry;
},
}),
masked: { xtype: 'loadmask',message: 'loading' },
onLoad: function (store) {
this.unmask();
console.log('list loaded');
this.fireEvent("productListLoadedCommand", this,store);
},
}
],
listeners: [
{
delegate: "#product-list-view",
event: "itemtap",
fn: function (list, index, target, record) {
console.log(index);
console.log('list selection command fired');
this.fireEvent("productListSelectedCommand", this,index,record);
}
}
],
style: 'background-image: -webkit-gradient(linear, left top, right bottom, color-stop(0, #FDFDFD), color-stop(1, #DBDBDB));background-image: linear-gradient(to bottom right, #FDFDFD 0%, #DBDBDB 100%);'
}//End of config
});//End of Define

在这个实际视图上方,我曾经显示列表。我的问题是我尝试了onLoad()方法,它可以工作,但我想在我的控制器中做所有的事情,让它更清楚。

正如您所看到的,我的itemTap事件已在Controller中通过激发事件进行了处理。但这对load事件不起作用。

正如@Jimmy所提到的,列表中并没有onLoad方法。然而,有几种方法可以解决这个问题。我对您想要实现的理解是,当加载支持列表的存储时,您希望从ProductList实例(而不是list)激发一个事件,以便在控制器中您可以将control配置为:

control: {
ProductList: {
productListSelectedCommand: 'productListSelectCommand',
productListLoadedCommand: 'productListLoadedCommand'
}
}

如果是这样,那么我们可以修改现有ProductList类中的侦听器以执行以下操作:

listeners: [
{
delegate: "#product-list-view",
event: "itemtap",
fn: function (list, index, target, record) {
console.log(index);
console.log('list selection command fired');
this.fireEvent("productListSelectedCommand", this,index,record);
}
},
{
delegate: "#product-list-view",
event: "show",
fn: function (list) {
var store = list.getStore();
var handler = function() {
list.unmask();
console.log('list loaded');
this.fireEvent("productListLoadedCommand", this, store);
};
if (store.isLoaded()) {
handler.apply(this)
} else {
list.getStore().on('load', handler, this);
}
}
}
]

它的作用是显示列表,然后获取它的存储,如果存储已经加载,则调用处理程序,否则直接在其上注册load侦听器。注意,这里的this对象将是ProductList,而不是product-list-view

根据Sencha Touch文档,我没有看到Ext.dataview.ListonLoad函数。但是,列表中包含的Ext.data.Store有一个load事件侦听器。因此,您的事件侦听器可能应该在数据存储中,而不一定在列表本身中。

在控制器的启动方法中,您可以为Store的加载事件设置一个监听器,如下所示:

launch: function () {        
// your store should be setup in your Ext.application
Ext.getStore('NameOfStore').on('load', this.productListLoadedCommand);
},
productListLoadedCommand: function(store, records, successful, operation, eOpts) {
// do some after load logic
}

您还应该为控制器中的列表设置事件侦听器。您应该不需要在视图配置中创建一个侦听器,只用于调用Controller中的fireEvent方法。相反,在控制器中执行所有事件处理。要在控制器中获得列表上的句柄,请在Ext.define中为WaxiApp.view.ProductViews.ProductList添加一个xtype: 'productlist'。然后,将您的列表作为ref添加到控制器的配置中,并为控件中的列表附加itemtap事件,如下所示:

config: {
ref: {
productList: 'productlist'
},
control: {
productList: {
itemtap: 'productListSelectCommand'
}
}
},
productListSelectCommand: function (list, index, target, record, e, eOpts) {
// do some itemtap functionality
}

最后,你的控制器可能看起来像这样:

Ext.define('MyApp.controller.Controller', {
extend: 'Ext.app.Controller',
requires: [
// what is required
],
config: {
ref: {
productList: 'productlist'
},
control: {
productList: {
itemtap: 'productListSelectCommand'
}
}
},
launch: function () {        
// your store should be setup in your Ext.application
Ext.getStore('NameOfStore').on('load', this.productListLoadedCommand);
},
productListLoadedCommand: function(store, records, successful, operation, eOpts) {
// do some after load logic
// this.getProductList() will give you handle of productlist
},
productListSelectCommand: function (list, index, target, record, e, eOpts) {
// do some itemtap functionality
}
}

最后,不要忘记在Ext.define中为您的WaxiApp.view.ProductViews.ProductList添加一个xtype: 'productlist'。我不确定您对Sencha Touch应用程序设计的总体体验,但这里有一个很好的参考,可以帮助您了解它们的视图、模型、商店和控制器结构。

我找到了解决方案,并发布了我的自己的解决方案。

ProductList.js

Ext.define('WaxiApp.view.ProductViews.ProductList', {
extend: 'Ext.Container',
alias: "widget.ProductList",
requires: [
'Ext.Img',
],
initialize: function () {
this.add([
{
xtype: 'list',
id: 'product-list-view',
store: 'ProductsList',
masked: { xtype: 'loadmask', message: 'loading' },
//onLoad is not a listener it's private sencha touch method used to unmask the screen after the store loaded
onLoad: function (store) {
this.unmask();//I manually unmask, because I override this method to do additional task.
console.log('list loaded');
this.fireEvent("productListLoadedCommand", this, store);
}
,
//Painted is event so added it to listener, I saw fee document state that, add event like Painted and show should to added to the
//Component itslef is best practice. 
listeners: {
order: 'after',
painted: function () {
console.log("Painted Event");
this.fireEvent("ProductListPaintedCommand", this);
},
scope: this
//This is also very important, because if we using this in card layout
//and changing the active view in layout cause this event to failed, so
//setting scope to this will help to receive the defined view instead of this list component.
}
}]);
},
config: {
listeners: [
{
delegate: "#product-list-view",
event: "itemtap",
fn: function (list, index, target, record) {
console.log(index);
console.log('list selection command fired');
this.fireEvent("productListSelectedCommand", this, index, record);
}
}
],
}//End of config
});//End of Define

ProductViewController.js

/// <reference path="../../touch/sencha-touch-all-debug.js" />

Ext.define("WaxiApp.controller.ProductsViewController", {
extend: "Ext.app.Controller",
listStoreNeedLoad:true,
config: {
refs: {
ProductContainer: "ProductList",
ProductList: "#product-list-view",
ProductDetailView:"ProductDetail"
},
control: {
ProductContainer:{
productListSelectedCommand: "onProductListSelected",
ProductListPaintedCommand: "onProductListPainted"
},
ProductList:{
productListLoadedCommand: "onProductListLoaded"        
}
}//End of control
},//End of config
// Transitions
getstore:function(){
return Ext.ComponentQuery.query('#product-list-view')[0].getStore();
},
onProductListPainted:function(list)
{
//Check for if need to load store because painted event called every time your view is painted on screen
if (this.listStoreNeedLoad) {
var store = this.getstore();
this.getstore().load();
}
},
onProductListLoaded:function(list,store)
{
this.listStoreNeedLoad = false;
var index = 0;
//Iterate through record and set my select Index
store.each(function(record,recordid){
console.info(record.get("isNeedInventry"));
if (record.get("isNeedInventry")) {
return false;
}
index++;
});
console.log('list load event fired');
if(Ext.os.deviceType.toLowerCase()!='phone')
{
this.setRecord(store.getAt(index));
list.select(index);
}
}
})//End of define

最新更新