0

我将 Ext JS 5.x 与 Sencha Touch 一起使用,并尝试迁移到 Sencha 建议的通用现代应用程序。然而,感觉好像有几件事发生了变化,并且没有按预期工作。

我正在使用虚拟商店通过 AJAX 将数据加载到一个简单的列表中。我现在想在加载列表时选择第一个(或条件不同的记录)。

Ext.define('Fiddle.model.User', {
  extend: 'Ext.data.Model',
  fields: ['name', 'email']
})

Ext.define('Fiddle.view.ListController', {
  extend: 'Ext.app.ViewController',
  alias: 'controller.test-list',
  listen: {
    store: {
        'test-users': {
            beforeload: function() {
                //Doesn't work
                console.log('before')
            }
        }
    }
},
onListItemTap: function(list, record) {
    this.fireEvent('select', this);
    console.log('selected');
}
});

Ext.define('Fiddle.store.Users', {
  extend: 'Ext.data.virtual.Store',
  alias: 'store.test-users',
  model: 'Fiddle.model.User',
  pageSize: 125,
  leadingBufferZone: 125,
  proxy: {
    type: 'ajax',
    url: 'data1.json',
    reader: {
        rootProperty: 'result.users',
        successProperty: 'result.success',
        totalProperty: 'result.total'
    }
  },
  listeners: {
    load: function(){
        // Doesn't trigger
        console.log('loaded');


    },
    scope: this
  }
});
Ext.define('Fiddle.view.List', {
  extend: 'Ext.List',
  xtype: 'test-list',
  controller: 'test-list',
  viewModel: {
    stores: {
        users: {
            type: 'test-users',
            listeners: {
                load: function(){
                    // Doesn't trigger
                    console.log('loaded');
                },
                scope: this
            }
        }
    }
        },
  bind: {
    store: '{users}'
  },
  itemTpl: '{name}. {email}',
  infinite: true,
  listeners: {
    select: 'onListItemTap'
  },
  initialize: function(){
    var me = this;
    this.callParent(arguments);

    /*Doesn't work as store seems to be not bound yet
    this.select(0)
    this.store.on('load', function(){
       console.log('loaded');
       this.select(0);
    });
    */

    //Does work, but dirty
    Ext.defer(function () {
        //this.select(0);
        //console.log(me.getStore());
    }, 500, me);
  },
  afterRender: function() {
    this.callParent()
    // Doesn't work, shouldn't the store be available/loaded after its 
  rendered?
    console.log(this.getStore()); //null
  }
})
Ext.application({
  name: 'Fiddle',

  launch: function () {
    Ext.Viewport.add({
        xtype: 'test-list'
    })
  }
})

问题: 1)我的看法是在视图的初始化函数中商店不可用,因此我不能在那里添加一个监听器。

2)无论是在商店本身,也不是在视图模型中,也不是在控制器中,我都可以添加一个监听器。如果我重写stores load 方法并手动触发load 事件,所有监听器都开始工作

// Fiddle.store.Users.load
load: function() {
  this.callParent(arguments);
  this.fireEvent('load');
}

是不是所有这些标准监听器都没有在现代工具包中实现,或者我错过了什么?

3)我试图挂钩afterRender视图的方法,但商店在那里也不可用,即使每个命名列表包括数据应该已经呈现..

4) 无论我添加 autoLoad: false 还是 true,商店似乎都会一直自动加载。

我以前的版本从来没有遇到过任何问题,现代工具包在当前状态下只是有问题还是我做错了什么?

小提琴

4

1 回答 1

0
  1. 如果商店是全局商店,您可以将其添加到应用程序的stores属性中,然后在任何视图被实例化之前就可以使用它。
  2. 从源代码看来,虚拟商店目前没有触发load事件。不确定这是否是一个错误,您可能需要询问 Sencha 支持。既然你让我好奇,请在这里报告答案。
  3. afterRender在列表渲染完成后调用,但 store 仅在组件树渲染完成后才绑定。如果您需要更早可用的商店,请参阅我对 (1) 的回答。
  4. 当存储由于分页而绑定到列表时,虚拟存储会“自动加载”。该列表知道需要哪个页面大小,并设置存储的页面大小,这会触发重新加载。console.trace()您可以通过添加自定义加载功能自己找出答案;它将输出调用的完整堆栈跟踪。您必须询问 Sencha 支持是否有可能摆脱自动重新加载。

load附带说明一下,对于虚拟商店来说,选择每个事件的第一条记录是很奇怪的。滚动时,虚拟商店会动态加载其他记录页面。如果仅仅加载一个新页面就导致选择改变,这对用户来说会很奇怪。

于 2018-05-03T14:59:11.997 回答