【问题标题】:Sencha Touch 2 List layout with ToolbarSencha Touch 2 带有工具栏的列表布局
【发布时间】:2012-02-15 13:33:46
【问题描述】:

我有一个列表,我正在使用一个停靠在顶部的工具栏。此列表还包含一个 indexBar。工具栏似乎将列表向下推。因此 indexBar 没有正确垂直对齐,当我向下滚动列表并到达最后一项时,它没有正确显示。有谁知道如何正确布局,以便工具栏不会将列表向下推?这是我的代码:

app.customerList = Ext.define('CustomerList', {
    constructor: function() {        
        this.listComponent = Ext.create('Ext.List', {
            itemTpl: '<div class="contact">{first_name} <strong>{last_name}</strong></div>',
            store: customerListStore,
            id: 'customer_list',
            grouped: true,
            indexBar: true,
            listeners: {
                itemtap: {
                    fn: function (list, index, item, evt) {

                    },
                    element: 'element'
                }
            }
        });

        this.listWrapper = Ext.create('Ext.Panel', {
            fullscreen: true,
            layout: 'fit',
            items: [
                {
                    xtype: 'toolbar',
                    docked: 'top',
                    title: 'Customers',
                    items: [
                        {
                            xtype: 'button',
                            text: 'Home',
                            ui: 'back',
                            listeners: {
                                tap: {
                                    fn: function() {

                                    },
                                    element: 'element'
                                }
                            }                            
                        }
                    ]
                },
                this.listComponent
            ]
        });

    }
});

如您所见,我正在从商店获取数据。我可以通过为列表提供底部的 css 规则来解决这个问题:38px,但我知道这是一个 hack,所以我宁愿不这样做。我看过名单上的煎茶视频,他们谈到了这个确切的困境。他们的解决方案是将列表放在包装器中,工具栏停靠在包装器中。所以我这样做了,但我仍然无法让它按应有的方式布局。

【问题讨论】:

    标签: extjs sencha-touch-2


    【解决方案1】:

    这似乎是您的代码的问题,而不是框架的错误。

    我将假设您希望最终结果是一个可滚动的列表,屏幕大小,顶部有一个工具栏。

    以下是一些说明,说明您需要更改哪些内容才能实现这一点:

    1. 使用Ext.define 定义新类时,您不需要将其设置为引用(在您的情况下为app.customerList),因为引用是使用传递的第一个字符串自动创建的。所以在你的情况下,你正在这样做:

      app.customerList = Ext.define('CustomerList', { ... });
      

      但是,你应该这样做:

      Ext.define('app.customerList', { ... });
      

      定义好之后,你可以在任何你喜欢的地方重用这个类,就像这样:

      `var view = Ext.create('app.customerList');
      

      我还想在这里指出,使用 app.customerList 不是 Sencha 建议您对命名约定做的事情,所以我建议您在有时间阅读时查看他们的 Class System Guide关于事物应该如何命名。

    2. 当你定义一个类时,99% 的时间你需要扩展另一个类。在您的情况下,您应该扩展 Ext. Container,因为我们要创建包含列表和停靠工具栏的最外层组件(您定义为 this.listWrapper)。

    3. 在 Sencha Touch 中扩展类时,不应覆盖 constructor 方法,而应使用 initialize 方法。在这个方法中,我们将添加停靠的工具栏和我们的列表。它应该是这样的:

      initialize: function() {
          this.callParent();
      
          this.listComponent = Ext.create('Ext.List', {
              itemTpl: '<div class="contact">{first_name} <strong>{last_name}</strong></div>',
              store: customerListStore,
              id: 'customer_list',
              grouped: true,
              indexBar: true,
              listeners: {
                  itemtap: {
                      fn: function (list, index, item, evt) {
      
                      },
                      element: 'element'
                  }
              }
          });
      
          this.add([
              {
                  xtype: 'toolbar',
                  docked: 'top',
                  title: 'Customers',
                  items: [
                      {
                          xtype: 'button',
                          text: 'Home',
                          ui: 'back',
                          listeners: {
                              tap: {
                                  fn: function() {
      
                                  },
                                  element: 'element'
                              }
                          }
                      }
                  ]
              },
              this.listComponent
          ]);
      }
      

      从这个 sn-p 中有几件事要记住:

      • 总是需要调用initialize 中的父类,因为父类可能正在执行我们需要的一些逻辑。您只需拨打this.callParent();即可。
      • 首先我们定义我们的listComponent,稍后我们将把它插入到这个app.customerList容器中。
      • 接下来我们调用this.add 并带有一个对象数组。此方法将在初始化时将我们的项目插入到我们的新容器类中。我们传递的第一个对象是工具栏的配置 - 与您的代码相同。作为数组中的第二个对象,我们传递listComponent
    4. 我们希望新容器类中的列表可以扩展到容器的大小,因此我们可以通过将fitlayout 配置添加到我们类的配置块中来实现。

      config: {
          layout: 'fit'
      }
      

      请记住,此配置块仅在使用 Ext.define 定义新类时使用。如果您使用Ext.create,或者将新组件作为对象传递(就像我们上面所做的那样),则不需要将它们放在这个特殊对象中。

    5. 最后,您不需要使用fullscreen 配置。相反,我们可以只创建新类的实例并将其直接添加到Ext.Viewport

      var customerList = Ext.create('CustomerList');
      Ext.Viewport.add(customerList);
      
      // add this point you can reference the listComponent without the customerList like this:
      console.log(customerList.listComponent.getStore());
      

    您的自定义类的最终代码是:

    Ext.define('CustomerList', {
        extend: 'Ext.Container',
    
        config: {
            fullscreen: true,
            layout: 'fit'
        },
    
    initialize: function() {
        this.callParent();
    
        this.listComponent = Ext.create('Ext.List', {
            itemTpl: '<div class="contact">{first_name} <strong>{last_name}</strong></div>',
            store: customerListStore,
            id: 'customer_list',
            grouped: true,
            indexBar: true,
            listeners: {
                itemtap: {
                    fn: function (list, index, item, evt) {
    
                    },
                    element: 'element'
                }
            }
        });
    
        this.add([
            {
                xtype: 'toolbar',
                docked: 'top',
                title: 'Customers',
                items: [
                    {
                        xtype: 'button',
                        text: 'Home',
                        ui: 'back',
                        listeners: {
                            tap: {
                                fn: function() {
    
                                },
                                element: 'element'
                            }
                        }
                    }
                ]
            },
            this.listComponent
        ]);
    }
    });
    
    var customerList = Ext.create('CustomerList');
    Ext.Viewport.add(customerList);
    
    // add this point you can reference the listComponent without the customerList like this:
    console.log(customerList.listComponent.getStore());
    

    对完整的重构感到抱歉,但我想我会向您展示编写这样的自定义类的正确方法。

    【讨论】:

    • 感谢您的详细解答。我继续在我的应用程序中重写了一堆东西,我相信我现在正确地使用了类系统。但是,我仍然遇到工具栏将我的内容向下推的问题。它不仅在列表组件中,而且在所有内容中。我有一个带有“卡片”布局的主容器,然后我正在向其中添加内容。但似乎我的工具栏仍在向下推送内容。我想我可能会为此提出另一个问题。
    • 确保有 HTML5 Doctype - 这可能会导致该问题 - &lt;!DOCTYPE html&gt;。如果没有,请在此处或 Sencha 论坛上创建另一个问题,并附上一个测试用例,我可以看看。
    • 刚刚想通了...我不敢相信我做到了,我的文档类型中有 'hmtl' 而不是 'html'。一旦我改变了它,我的所有问题都得到了解决。再次感谢您的帮助。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-17
    • 2012-02-17
    • 1970-01-01
    相关资源
    最近更新 更多