首页 > 解决方案 > 在 Sencha 应用程序中重用相同组件时重复引用

问题描述

假设我们已经定义了一个我们想在单个应用程序中重用的组件(例如 FieldSet)(例如在 2 个不同的模式窗口中显示/使用它)。这个 FieldSet 有一个引用,我们用它来访问它。目标是让这两个窗口包含独立的字段集,这样我们就可以分别控制和收集每个窗口的输入。

这是演示问题的示例小提琴。只要任何函数触发任何lookupReference(...)调用,Sencha 就会针对字段集发出“重复引用”警告。它在每个窗口上正确地创建了两个不同的字段集组件(通过分配不同的 id),但未能正确分配/定位引用。结果,对这些窗口字段集之一的任何操作都将在“未知”字段集上执行(可能在第一个创建的字段集上),从而弄乱了 UI 行为。

我看到 Sencha 在对引用进行操作时理解要使用哪个组件是一个问题,但是应该有一种方法可以多次重用同一个组件而不会混淆实例。任何帮助是极大的赞赏。

标签: extjs

解决方案


根据ViewController上的文档:

视图控制器是可以附加到特定视图实例的控制器,因此它可以管理视图及其子组件。视图的每个实例都会有一个新的视图控制器,因此实例是隔离的。

这意味着您singleton在 ViewController 上的使用不正确,因为它必须绑定到单个视图实例。

要解决此问题,我建议对您的Fiddle进行一些修改,主要是singleton: true从您的 VC 类中删除 ,通过 访问视图lookup,并让他们的 VC 通过getController访问您的func方法。

Ext.application({
    name: 'Fiddle',
    launch: function () {

        /**
         * @thread https://stackoverflow.com/questions/67462770
         */
        Ext.define('fsContainerHandler', {
            extend: 'Ext.app.ViewController',
            alias: 'controller.fsContainerHandler',
            // TOOK OUT singleton: true
            func: function () {
                var x = this.lookupReference('fsRef');
                alert(x);
            }
        });

        Ext.define('fsContainer', {
            extend: 'Ext.container.Container',
            xtype: 'xFSContainer',
            controller: 'fsContainerHandler',
            items: [{
                xtype: 'fieldset',
                title: 'myFieldset',
                reference: 'fsRef'
            }]
        });

        Ext.define('mainContainerHandler', {
            extend: 'Ext.app.ViewController',
            alias: 'controller.mainContainerHandler',
            singleton: true,
            onButton1Click: function () {
                var win = this.getView().window1;
                win.show();
                // CHANGED LOGIC
                win.lookup('theContainer').getController().func();
            },
            onButton2Click: function () {
                var win = this.getView().window2;
                win.show();
                // CHANGED LOGIC
                win.lookup('theContainer').getController().func();
            }
        });

        Ext.define('mainContainer', {
            extend: 'Ext.container.Container',
            width: 400,
            controller: 'mainContainerHandler',
            window1: null,
            window2: null,
            initComponent: function () {
                this.window1 = Ext.create('window1');
                this.window2 = Ext.create('window2');
                this.callParent(arguments);
            },
            items: [{
                xtype: 'button',
                text: 'Window 1',
                reference: 'btn1',
                handler: mainContainerHandler.onButton1Click,
                scope: mainContainerHandler
            }, {
                xtype: 'button',
                text: 'Window 2',
                reference: 'btn2',
                handler: mainContainerHandler.onButton2Click,
                scope: mainContainerHandler
            }]
        });

        Ext.define('window1', {
            extend: 'Ext.window.Window',
            title: 'Window1',
            modal: true,
            width: 100,
            height: 100,
            closeAction: 'hide',
            // ADDED referenceHolder
            referenceHolder: true,
            items: [{
                xtype: 'xFSContainer',
                // ADDED reference
                reference: 'theContainer'
            }]
        });

        Ext.define('window2', {
            extend: 'Ext.window.Window',
            title: 'Window2',
            modal: true,
            width: 100,
            height: 100,
            closeAction: 'hide',
            // ADDED referenceHolder
            referenceHolder: true,
            items: [{
                xtype: 'xFSContainer',
                // ADDED reference
                reference: 'theContainer'
            }]
        });

        Ext.create('mainContainer', {
            renderTo: document.body
        });
    }
});

推荐阅读