ExtJS - 如何将组件配置选项传递给XTemplates? [英] ExtJS - How to pass Component config options to XTemplates?

查看:172
本文介绍了ExtJS - 如何将组件配置选项传递给XTemplates?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

  Ext.define('Aft.view.comments。 CommentList',{
extends:'Ext.view.View',
xtype:'comments-list',

参数:false,

tpl:new Ext.XTemplate(
'< tpl for =。>',
'< div class =comment>',
// some code here
'< div class =fault>',
'< tpl if =this.parameter>',
//某些代码也在这里
'< / tpl>',
'< / div>',
'< / div>',
'< / tpl>',
{
strict:true,
//其他方法和字段
}),

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 ',
参数:false
}
]

我把它作为参数,我把所有配置看起来像我自定义类的其他实例一样被共享。所以每个评论列表的参数都设置为true,或者每一个都设置为false。我显然缺少一些东西,但似乎这个话题也为别人造成混乱。尽管我没有找到正确的方法来解决这个问题。我已经尝试过各种组合的config,factoryConfig和变量直接在类定义,但没有什么似乎工作。



因此,我将非常感谢一个解决方案,或在至少是博客文章或文档的宝贵链接。非常感谢您提前。



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

解决方案

原因是你的 tpl 原型,因此在实例之间共享。这是我最大的宠物对抗Ext在原型上设置对象的方式,而不了解真正的意思。这也意味着如果您需要,您无法访问 ,如我在示例中所看到的,因为您需要将配置传递到模板中。



您的好问题实际上是给我一个很好的简化示例,证明了我一直试图对我的团队(一直在开发Ext-JS,因为它是yui-ext );



您的 tpl 对象正在 Aft.view.comments.CommentsList .prototype ,因此正在共享。



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

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

//原型总是可以在原型上,因为如果你写,你将
//修改实例上的一个属性,而不是原型
参数:false,

initComponent:function(){
this.tpl = new Ext.XTemplate(
'< tpl for =。>' ,
'< div class =comment>',
// some code here
'< div class =fault>',
'< ; tpl if =this.parameter>',
//一些代码也在这里
'< / tpl>',
'< / div>',
'< / div>',
'< / tpl>',
{
strict:true,
参数:this.parameter
});
this.callParent(arguments);
}
});



Ext Prototype Rant



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



如果我们在HTML中有一些关于代码
项的假设,可能会打破类:[{xtype:'comments-list',tpl:'< ; div> Broke you< / div>'}]

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



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

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

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


I defined a following class extending 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);
  }
});

As you can see, I am trying to pass a boolean parameter from outside of the component to XTemplate inside of it. I am trying to do it, because the component is used in 3 different places. In one of them, I want it to look slightly different (just without one div). I figured out that parametrised XTemplate would be a nice solution, but I can not force it to work. I am creating the component like this:

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

And regardless of what I put as parameter, everything that I put in config seems to be shared among other instances of my custom class. So either every CommentsList has parameter set to true, or every has it set to false. I obviously am missing something, but it seems that this topic creates confusion for others too. Despite that I did not find a proper way to solve this. I have tried various combinations with config, factoryConfig and variables straight in class definition, but nothing seems to work.

Therefore, I would be very grateful for a solution, or at least a valuable link to blog post or documentation. Thank you very much in advance.

If that is relevant, I am using ExtJS 6 classic.

解决方案

The reason is that your tpl is on the prototype and is therefore shared between instances. That is my biggest pet peeve against Ext's way of setting objects on the prototype without understanding what that really means. That also means you don't have access to this if you need it, as you'll see in my example because you need to "pass down" the configuration into the template.

Your great question is actually giving me a nice simplified example that proves a point I always try to make to my teams (been developing Ext-JS since it was yui-ext);

Your tpl object is being set on Aft.view.comments.CommentsList.prototype so it's being shared.

The correct solution is to initialize tpl from the constructor (or initComponent) so that a new template is created for each instance. See 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

When setting something on the prototype, it means that a caller could still override it when passing in a config object. For example, in the class above I could override the tpl (and break the functionality of the class) when instantiating it.

// 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>'}]

If you define it within initComponent, you are going to override anything the user passes in. Use that wisely. If you define it on the prototype, it's simply a default and your code shouldn't depend on it.

Obviously, we still have to keep in mind that objects on the prototype are shared, so if you want a default object that is not shared, you should use

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

And lastly, if you have an object that does not change (defaults), then it doesn't matter and it would be good to store in on the prototype to save memory, but you have to be careful that you don't modify it (unless you can use Object.freeze).

这篇关于ExtJS - 如何将组件配置选项传递给XTemplates?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆