【问题标题】:ExtJS - How to pass Component config options to XTemplates?ExtJS - 如何将组件配置选项传递给 XTemplates?
【发布时间】:2015-11-13 12:04:09
【问题描述】:

我定义了一个扩展 Ext.view.View 的以下类:

Ext.define('Aft.view.comments.CommentsList', {
  extend: 'Ext.view.View',
  xtype: 'comments-list',

  parameter: false,

  tpl: new Ext.XTemplate(
    '<tpl for=".">',
    '  <div class="comment">',
           // some code here
    '    <div class="fault">',
    '      <tpl if="this.parameter">',
             // some code also here         
    '      </tpl>',
    '    </div>',
    '  </div>',
    '</tpl>',
    {
      strict: true,
      // other methods and fields
    }),

  initComponent: function() {
    this.config = Ext.apply({}, this.config);
    this.tpl.config.parameter = this.config.parameter;
    this.callParent(arguments);
  }
});

如您所见,我试图将一个布尔参数从组件外部传递到其中的 XTemplate。我正在尝试这样做,因为该组件在 3 个不同的地方使用。在其中一个中,我希望它看起来略有不同(只是没有一个 div)。我发现参数化的 XTemplate 将是一个不错的解决方案,但我不能强迫它工作。我正在创建这样的组件:

items: [
    {
        xtype: 'comments-list',
        parameter: false
    }
]

不管我把什么作为参数,我放在配置中的所有东西似乎都在我的自定义类的其他实例之间共享。因此,要么每个 CommentsList 的参数都设置为 true,要么每个 CommentsList 的参数都设置为 false。我显然遗漏了一些东西,但似乎这个话题也给其他人带来了困惑。尽管如此,我没有找到解决这个问题的正确方法。我在类定义中直接尝试了 config、factoryConfig 和变量的各种组合,但似乎没有任何效果。

因此,我将非常感谢您提供解决方案,或者至少是博客文章或文档的有价值链接。非常感谢您。

如果相关,我正在使用 ExtJS 6 经典版。

【问题讨论】:

    标签: extjs extjs6


    【解决方案1】:

    原因是您的tplprototype and is therefore shared between instances 上。这是我对 Ext 在原型上设置对象的方式最大的不满,而没有理解它的真正含义。这也意味着如果需要,您无权访问this,正如您将在我的示例中看到的那样,因为您需要将配置“传递”到模板中。

    你的好问题实际上给了我一个很好的简化示例,证明了我一直试图向我的团队提出的一个观点(从 yui-ext 开始一直在开发 Ext-JS);

    您的 tpl 对象被设置在 Aft.view.comments.CommentsList.prototype 上,因此它正在被共享。

    正确的解决方案是从构造函数(或initComponent)初始化tpl,以便为每个实例创建一个新模板。见https://fiddle.sencha.com/#fiddle/111v

    Ext.define('Aft.view.comments.CommentsList', {
      extend: 'Ext.view.View',
      xtype: 'comments-list',
    
      // Primitives are always OK on prototypes because if you write, you will
      // modify a property on the instance, not the prototype
      parameter: false, 
    
      initComponent: function() {
        this.tpl = new Ext.XTemplate(
        '<tpl for=".">',
        '  <div class="comment">',
               // some code here
        '    <div class="fault">',
        '      <tpl if="this.parameter">',
                 // some code also here         
        '      </tpl>',
        '    </div>',
        '  </div>',
        '</tpl>',
        {
          strict: true,
          parameter: this.parameter
        });
        this.callParent(arguments);
      }
    });
    

    Ext Prototype Rant

    在原型上设置某些东西时,这意味着调用者在传入配置对象时仍然可以覆盖它。例如,在上面的类中,我可以在实例化它时覆盖tpl(并破坏类的功能)。

    // Will likely break the class if we have some assumptions in the HTML about the code
    items: [{xtype: 'comments-list', tpl: '<div>Broke you</div>'}]
    

    如果您在initComponent 中定义它,您将覆盖用户传入的任何内容。明智地使用它。如果你在原型上定义它,它只是一个默认值,你的代码不应该依赖它。

    显然,我们仍然要记住原型上的对象是共享的,所以如果你想要一个不共享的默认对象,你应该使用

    initComponent: function() {
       Ext.applyIf(this, {
          someProp: {defaultObject: true}
       });
       this.callParent();
    }
    

    最后,如果你有一个不会改变的对象(默认值),那没关系,最好存储在原型中以节省内存,但你必须小心不要'不要修改它(除非你可以使用Object.freeze)。

    【讨论】:

    • 完美运行,非常感谢!现在我更好地理解了 ExtJS 类模型,很好的解释。 :-)
    猜你喜欢
    • 2017-08-13
    • 2017-11-23
    • 1970-01-01
    • 2020-06-04
    • 2013-01-01
    • 2016-06-10
    • 1970-01-01
    • 1970-01-01
    • 2020-07-08
    相关资源
    最近更新 更多