【问题标题】:Tagfield with html encoded displayField in Extjs 6Extjs 6中带有html编码displayField的标签字段
【发布时间】:2015-08-18 13:06:33
【问题描述】:

在升级到 Extjs 6 之前,我们使用 tagfield 组件,其中 displayFieldExt.String.htmlEncode('description'),其中 description 是商店记录的描述字段。此字段不仅包含简单的文本,而是采用以下形式:<img src="link..." style="..."/>&nbspRECORD_DESCRIPTION。使用htmlEncode 函数,它实际上会使用链接的图像和记录的描述来呈现标签字段的记录。

但是在升级到版本 6 后,它就停止了工作。它现在只生成全文而不是渲染图像。就像htmlEncode 突然停止工作一样。问题是,在ItemSelector 字段中,我们执行相同的操作,使用完全相同的方法,一切都可以完美运行。他们是否破坏了tagfield 组件以致无法显示html?

无论如何,我怎样才能重现我之前所做的事情?我尝试使用 displayTpl 配置,但它似乎不起作用。

【问题讨论】:

    标签: javascript html extjs extjs6


    【解决方案1】:

    而不是 Ext.String.htmlEncode('description') 在 displayField 中尝试 'description'。 DisplayField 会影响您在选择时看到的内容,为此,它将显示您的 HTML。它还会影响它显示您所做选择的方式,并且似乎没有办法在那里显示 HTML。它显示为纯文本。还有另一个属性 labelTpl 用于格式化您已经选择的项目。您可以使用它来仅显示您已经选择的事物的名称。 (LabelTpl 用于显示格式化的 HTML,但在 ExtJs6 中不显示。)假设您的商店记录也有一个“名称”字段,它只是纯文本;你可以把它放在花括号里:

    xtype:'tagfield',
    displayField: 'description',
    labelTpl: '{name}',
    ...
    

    然后,您将在进行选择时获得格式化的 HTML,并在所选项目中获得纯文本。这是迄今为止我想出的最好的。

    【讨论】:

      【解决方案2】:

      使用 ExtJS 6.5.3

      在为列表和标签创建复杂的显示语句方面,这是我能想到的最好的标签字段。

      显示器支持 CSS 和其他 HTML 标签 labelTpl 不支持纯文本以外的任何内容,但您可以覆盖它的 x-tagfield-item-text 样式,但是,要么全有,要么全无。

      {
                  cls: "triggerstagfield",
                  displayField: '[(values.key != "all") ? values.label + " (<b>" + values.key + "</b>)" : values.label]',
                  labelTpl: '{[(values.key != "all") ? values.label + " (" + values.key + ")" : values.label]}',
                  valueField: "key",
                  store: [{
                      "key": "all",
                      "label": "All"
                  }, {
                      "key": "880",
                      "label": "International House of Pancakes" 
                  }]                      
              },
      

      这是CSS

      .triggerstagfield .x-tagfield-item-text {
          font-weight: bold;
          font-size: 0.9em;   
      }
      

      【讨论】:

        【解决方案3】:

        我通过扩展内置标签字段,覆盖函数 getMultiSelectItemMarkup 来解决它。在那个函数中,我删除了标签上对 Ext.String.htmlEncode 的调用。

        有了这个,你可以使用

        { 
          xtype: 'tagfieldhtmllabel',
          labelTpl: '<span style="background-color:#{colorbg};">{name}</span>',
          ...
        }
        

        这是适用于 Ext 6.2.1 的代码

        Ext.define("Private.ui.TagFieldHtmlLabel", {
            extend: 'Ext.form.field.Tag',
            alias: 'widget.tagfieldhtmllabel',
        
            // TODO EXT UPGRADE. WHEN UPGRADING FROM 6.2.1 update this
            getMultiSelectItemMarkup: function() {
                var me = this,
                    childElCls = (me._getChildElCls && me._getChildElCls()) || '';
                // hook for rtl cls
                if (!me.multiSelectItemTpl) {
                    if (!me.labelTpl) {
                        me.labelTpl = '{' + me.displayField + '}';
                    }
                    me.labelTpl = me.lookupTpl('labelTpl');
                    if (me.tipTpl) {
                        me.tipTpl = me.lookupTpl('tipTpl');
                    }
                    me.multiSelectItemTpl = new Ext.XTemplate([
                        '<tpl for=".">',
                        '<li data-selectionIndex="{[xindex - 1]}" data-recordId="{internalId}" role="presentation" class="' + me.tagItemCls + childElCls,
                        '<tpl if="this.isSelected(values)">',
                        ' ' + me.tagSelectedCls,
                        '</tpl>',
                        '{%',
                        'values = values.data;',
                        '%}',
                        me.tipTpl ? '" data-qtip="{[this.getTip(values)]}">' : '">',
                        '<div role="presentation" class="' + me.tagItemTextCls + '">{[this.getItemLabel(values)]}</div>',
                        '<div role="presentation" class="' + me.tagItemCloseCls + childElCls + '"></div>',
                        '</li>',
                        '</tpl>',
                        {
                            isSelected: function(rec) {
                                return me.selectionModel.isSelected(rec);
                            },
                            getItemLabel: function(values) {
                                // UPGRADE - removed htmlEncode here
                                return me.labelTpl.apply(values);
                            },
                            getTip: function(values) {
                                return Ext.String.htmlEncode(me.tipTpl.apply(values));
                            },
                            strict: true
                        }
                    ]);
                }
                if (!me.multiSelectItemTpl.isTemplate) {
                    me.multiSelectItemTpl = this.lookupTpl('multiSelectItemTpl');
                }
                return me.multiSelectItemTpl.apply(me.valueCollection.getRange());
            }
        
        
        }); 
        

        【讨论】: