简体   繁体   English

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

[英]How to make HTML render properly into ExtJS tabs?

I am developing a simple JavaScript-based plugin architecture which allows for any JavaScript control from any framework (jQueryUI, ExtJS, etc). 我正在开发一个简单的基于JavaScript的插件体系结构,该体系结构允许来自任何框架(jQueryUI,ExtJS等)的任何JavaScript控件。 to be plugged into and reused on any web page. 可以插入并在任何网页上重复使用。 My plugins below happen to use ExtJS 4. 我下面的插件碰巧使用ExtJS 4。

The first plugin renders fine in the first tab. 第一个插件在第一个标签中呈现良好。 However, since the second tab hasn't yet rendered when the page loads, the second plugin (also a grid) is first rendering to the document body, and then it renders properly (the HTMLElement/div is moved) inside the tab when the tab is selected . 但是,由于第二个选项卡在页面加载时尚未呈现, 因此第二个插件(也是网格)会首先呈现到文档主体,然后在页面上正确显示(HTMLElement / div已移动)选项卡被选中 I'd like the plugin content to be hidden prior to rendering inside the tab. 我希望插件内容在选项卡内呈现之前被隐藏。 Also, when it it does render [when the tab is selected], horizontal scrollbars don't show unless I resize a column. 另外,当它确实呈现[选择选项卡时],除非我调整列的大小,否则不会显示水平滚动条。

Any ideas how to fix this? 任何想法如何解决这一问题?

Ideas: use something other than contentEl; 想法:使用contentEl以外的其他东西; leverage various ExtJS config options; 利用各种ExtJS配置选项; change my architecture. 改变我的架构。

Here is the plugin code: 这是插件代码:

(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);

And here's code using the plugin: 这是使用插件的代码:

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
      }]
    })
  ]
});

I can add it to an invisible container, but it feels dirty doing so: 我可以将其添加到不可见的容器中,但是这样做很脏:

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 这是一个例子

Here are a few problems with your code. 这是您的代码的一些问题。

What you are calling plugins are not plugins, they are just subclasses of Ext.grid.Panel . 您所说的插件不是插件,它们只是Ext.grid.Panel子类。 A plugin is something that adds functionality to an Ext.Component , but that is not what Stocks is doing. 插件是为Ext.Component添加功能的东西,但这不是Stocks所做的。 It's just what we call a preconfigured class. 这就是我们所谓的预配置类。

Here's what I would do, just make MyNamespace.Plugin.Stocks be a subclass of Ext.grid.Panel , you can now easily pass those as the items of a Ext.tab.Panel . 这就是我要做的,只需将MyNamespace.Plugin.Stocks作为Ext.grid.Panel的子类,您现在就可以轻松地将它们作为Ext.tab.Panel的项目Ext.tab.Panel Make sure you rename it, it's not a plugin. 确保将其重命名,它不是插件。

By giving your widget subclasses the alias: 'widget.stock-grid' , you can create them using just an object definition, without having to instantiate them, the framework will take care of rendering it only when needed (the tab is activated) 通过为窗口小部件子类提供alias: 'widget.stock-grid' ,您可以仅使用对象定义来创建它们,而无需实例化它们,框架将只在需要时渲染它(选项卡被激活)。

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

When using managed layouts, you cannot just simply copy a node into another container, because the node you copied in there won't have a managed layout. 使用托管布局时,您不能仅将一个节点复制到另一个容器中,因为您在其中复制的节点将没有托管布局。

Here's a modified version of your code that is written more like Ext-JS intended it. 这是代码的修改版本,其编写方式更像Ext-JS所预期的那样。 http://jsfiddle.net/NVfRH/10/ http://jsfiddle.net/NVfRH/10/

You can look into the generated HTML and you'll notice that the grid under orders only renders when you activate that tab. 您可以查看生成的HTML,您会注意到,仅当激活该选项卡时,订单下的网格才会呈现。

You should also notice that your grids weren't properly sizing themselves to fill the window, my code fixes that since they are correctly placed in the layout pipeline and obey the fit layout. 您还应该注意,您的网格无法正确调整自身大小以填充窗口,我的代码修复了这些问题,因为它们已正确放置在布局管道中并遵循fit布局。

Remaining Problems 仍然存在的问题

  • Your grids are sharing a store, notice that when you sort one, the other gets sorted, so you can't have them with different sorting. 您的网格共享一个商店,请注意,当您对一个网格进行排序时,另一个网格将被排序,因此您不能对它们进行不同的排序。
  • You were using a stateId , but then you were creating two instances with the same stateId , all stateIds must be unique 您使用了stateId ,但是随后创建了两个具有相同stateId实例,所有stateId必须唯一

And lastly, I must ask, were you really relieved when Chad Johnson changed his name to Chad Ochocinco? 最后,我必须问,当查德·约翰逊(Chad Johnson)更名为查德·奥乔辛科(Chad Ochocinco)时,您真的松了一口气吗? :) :)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM