如何使HTML正确呈现到ExtJS选项卡中?

时间:2012-12-07 18:24:24

标签: javascript plugins extjs4

我正在开发一个简单的基于JavaScript的插件架构,允许从任何框架(jQueryUI,ExtJS等)进行任何JavaScript控制。在任何网页上插入并重复使用。我的插件碰巧使用ExtJS 4。

第一个插件在第一个标签中呈现正常。但是,由于第二个选项卡在页面加载时尚未呈现,第二个插件(也是一个网格)首先呈现给文档正文,然后它正确渲染(HTMLElement / div被移动)选中标签时的标签。我希望在选项卡内部渲染之前隐藏插件内容。此外,当它确实渲染[选择选项卡时],除非我调整列的大小,否则不会显示水平滚动条。

任何想法如何解决这个问题?

提示:使用contentEl以外的内容;利用各种ExtJS配置选项;改变我的架构。

以下是插件代码:

(function(MyNamespace) {
  var gridDataStore = ...

  MyNamespace.Plugin.Chart = MyNamespace.Plugin.extend({
    return {
      initialize: function() {
        // ...
      },

      render: function() {
        var stockGrid = Ext.create('Ext.grid.Panel', {
          autoRender: true,
          autoShow: true,
          store: gridDataStore,
          header: false,
          stateId: 'stateGrid',
          columns: [
            {text: 'Symbol',      width: 75,  sortable: true, dataIndex: 'symbol'},
            {text: 'Description', width: 200, sortable: true, dataIndex: 'description'},
            {text: 'Quantity',    width: 75,  sortable: true, dataIndex: 'quantity'},
            {text: 'Last Price',  width: 85,  sortable: true, dataIndex: 'last_price'}
          ],
          viewConfig: {
            stripeRows: true,
            enableTextSelection: true
          }
        });

        return stockGrid.getEl().dom;
      }
    };
  }
})(MyNamespace);

以下是使用插件的代码:

var chart = new MyNamespace.Plugin.Chart();
var anotherPlugin = new MyNamespace.Plugin.Another();

var stocksWindow = Ext.create('Ext.Window', {
  title: 'Stocks',
  width: 600,
  height: 450,
  layout: 'fit',
  items: [
    Ext.create('Ext.tab.Panel', {
      activeTab: 0,
      items: [{
        title: 'Chart',
        autoScroll: true,
        contentEl: chartPlugin.render()  // RENDER FIRST PLUGIN IN FIRST TAB
      },{
        title: 'Something Else',
        autoScroll: true,
        contentEl: anotherPlugin.render()  // RENDER SECOND PLUGIN IN SECOND TAB
      }]
    })
  ]
});

我可以将它添加到一个不可见的容器中,但这样做会感觉很脏:

var container = document.createElement('div');
document.getElementsByTagName('body')[0].appendChild(container);
container.style.visibility = 'hidden';

var stockGrid = Ext.create('Ext.grid.Panel', {
  ...
  renderTo: container
  ...
});

Here's an example

1 个答案:

答案 0 :(得分:1)

以下是您的代码的一些问题。

你所谓的插件不是插件,它们只是Ext.grid.Panel的子类。插件可以为Ext.Component添加功能,但这不是Stocks正在做的事情。这就是我们称之为预先配置的类。

以下是我要做的事情,只需将MyNamespace.Plugin.Stocks作为Ext.grid.Panel的子类,您现在可以轻松地将其作为Ext.tab.Panel的项目传递。确保你重命名它,它不是一个插件。

通过为您的窗口小部件提供alias: 'widget.stock-grid'子类,您可以仅使用对象定义创建它们,而无需实例化它们,框架将仅在需要时(标签被激活)处理它?<​​/ p>

        Ext.create('Ext.tab.Panel', {
            activeTab: 0,
            items: [{
                title: 'Stocks',
                autoScroll: true,
                xtype: 'stock-grid'
            },{
                title: 'Orders',
                autoScroll: true,
                xtype: 'stock-grid'
            }]
        })

使用托管布局时,您不能简单地将节点复制到另一个容器中,因为您在其中复制的节点将没有托管布局。

这是您的代码的修改版本,其编写更像Ext-JS的意图。 http://jsfiddle.net/NVfRH/10/

您可以查看生成的HTML,您会注意到订单下的网格只会在您激活该标签时呈现。

你还应该注意到你的网格没有正确调整自己以填充窗口,我的代码修复了因为它们被正确放置在布局管道中并遵守fit布局。

剩余问题

  • 您的网格正在共享一个商店,请注意,当您对某个商店进行排序时,另一个商店会进行排序,因此您无法对其进行排序。
  • 您使用的是stateId,但之后您创建了两个具有相同stateId的实例,所有stateIds必须是唯一的

最后,我必须问,当查德·约翰逊改名为Chad Ochocinco时,你真的松了一口气吗? :)