You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ExtJS中实现第二个form.TextArea随第一个TextArea高度同步增长

问题背景

两个开启grow属性的Ext.form.TextArea组件,需要实现第一个文本域因内容输入自动增高时,第二个文本域高度同步跟随变化。
初始测试代码如下:

Ext.application({
name : 'Fiddle',

launch : function() {
    Ext.create('Ext.form.TextArea', {
        renderTo: Ext.getBody(),
        width: 500,
        grow: true,
        id: 'm1',
    });


Ext.create('Ext.form.TextArea', {
        renderTo: Ext.getBody(),
        width: 500,
        grow: true,
        id: 'm2',
    });
},
});

已尝试的无效方案

  • 直接给第二个文本域加bind配置绑定m1的height,未生效:
bind: {
height: '{m1.height}',
}
  • 直接获取DOM元素设置高度,未生效:
var el = Ext.get("m1");
var e2 = Ext.get("m2");
e2.setHeight(e1.getHeight());
原因说明
  1. 直接用Ext.create裸创建的组件没有挂载ViewModel上下文,bind配置根本找不到可解析的数据源,不可能生效;另外TextArea开了grow之后的高度调整是组件内部直接改输入框DOM高度,默认不会把高度变更同步成可绑定的响应式属性,就算有ViewModel也监听不到变化。
  2. Ext.get()拿到的是DOM元素的包装对象,不是Ext组件实例,在DOM层面调setHeight不会触发组件的布局重算,设完很快就会被组件自身的布局逻辑覆盖,等于白设。
实现方案

方案1:resize事件监听(最简便,无需修改原有代码结构)

TextArea开启grow后,内容变化触发高度调整时会对外抛出resize事件,事件回调参数会返回组件最新的宽高,直接在回调里同步第二个组件的高度即可。
注意:被同步高度的第二个TextArea需要关闭grow属性,避免两个组件的自动增高逻辑冲突、循环触发高度调整。
完整代码:

Ext.application({
    name: 'Fiddle',
    launch: function () {
        Ext.create('Ext.form.TextArea', {
            renderTo: Ext.getBody(),
            width: 500,
            grow: true,
            id: 'm1',
            listeners: {
                resize: function (sourceCmp, newWidth, newHeight) {
                    const targetCmp = Ext.getCmp('m2');
                    targetCmp.setHeight(newHeight);
                }
            }
        });

        Ext.create('Ext.form.TextArea', {
            renderTo: Ext.getBody(),
            width: 500,
            grow: false, // 必须关闭,避免高度逻辑冲突
            id: 'm2'
        });
    }
});

方案2:正确配置bind实现(符合MVVM绑定规范)

如果一定要用bind的方式实现,需要先给组件挂载ViewModel,同时将源TextArea的高度变更同步到ViewModel的响应式数据中,绑定才能生效。
完整代码:

Ext.application({
    name: 'Fiddle',
    launch: function () {
        Ext.create('Ext.container.Container', {
            renderTo: Ext.getBody(),
            viewModel: {
                data: {
                    textareaHeight: 60 // TextArea默认初始高度
                }
            },
            items: [
                {
                    xtype: 'textarea',
                    width: 500,
                    grow: true,
                    listeners: {
                        resize: function (sourceCmp, newWidth, newHeight) {
                            // 高度变化时同步更新ViewModel数据
                            sourceCmp.lookupViewModel().set('textareaHeight', newHeight);
                        }
                    }
                },
                {
                    xtype: 'textarea',
                    width: 500,
                    grow: false,
                    bind: {
                        height: '{textareaHeight}'
                    }
                }
            ]
        });
    }
});

注意事项

  • 获取Ext组件实例不要用Ext.get(),该方法仅返回DOM包装对象;要获取组件实例请使用Ext.getCmp(组件id),或通过lookup()、组件查询方法获取,尽量减少全局id的使用避免命名冲突。
  • 不要给两个TextArea同时开启grow属性,否则会出现高度循环触发的问题:源组件增高→设置目标组件高度→目标组件自身grow逻辑触发再次变高→反向触发布局调整,最终高度异常。

内容的提问来源于stack exchange,提问作者Jakub

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.31 00:36:26