簡體   English   中英

ExtJS可重用的視圖和控制器

[英]ExtJS reusable views and controllers

我剛開始使用Extjs時,並沒有什么基本的疑問。我創建了一個簡單的視圖(ScreenPropertiesPage),其中有1個選擇框和1個自定義視圖。 選擇框值更改后,將在控制器中更新視圖字段。 我已經完成了創建視圖和控制器的工作,該控制器具有用於onchange選擇框值的偵聽器並更新了關聯的視圖字段。

但是現在的問題是:在我的應用程序中,我必須創建4個ScreenPropertiesPage視圖的實例,並且從任何視圖觸發onchange事件時,始終會更新第一個視圖的文本框。 如何將事件合並到特定視圖? 組合控制器和視圖並重用它的最佳過程是什么(即使從我可以從中學習控制器視圖可重用性的文檔鏈接也是如此)? 任何幫助是極大的贊賞。

用於查看的代碼框架:

Ext.define('Configurator.view.screenproperties.ScreenPropertiesPage', {
    extend: 'Ext.container.Container',
    alias: 'widget.screenpropertiespage',
    requires: [
        'Configurator.store.screenproperties.ScreenProperties'
    ],
    autoScroll: true,

    config: {
        overLayMode: false
    },
    initComponent: function () {
        var me = this;
        this.items = [{
            xtype: 'container',
            componentCls: 'screenComboSelectorPanel',
            layout: {
                type: 'hbox',
                align: 'center',
                pack: 'center'
            },
            items: [{
                xtype: 'combo',
                store: Ext.create(
                    'Configurator.store.screenproperties.ScreenProperties'
                ),
                itemId: 'screenSelector',
                margin: 3,
                width: 400,
                listConfig: {
                    maxHeight: 200
                },
                fieldLabel: 'Screen Name',
                disabledCls: 'disabledBtn',
                disabled: me.getOverLayMode(),
                queryMode: 'local',
                emptyText: '-SELECT-',
                valueField: 'screenName',
                displayField: 'screenName',
                forceSelection: true,
                selectOnTab: true,
                autoSelect: true,
                height: 25,
                tpl: Ext.create('Ext.XTemplate',
                    '<tpl for=".">',
                    '<div class="x-boundlist-item comboContainer "><div class="rowExpanedrTextArea " style="">{screenName}   </div>{[this.isExpandable(xkey,parent,values,xindex)]}</div>',
                    '</tpl>'
                ),
                displayTpl: Ext.create('Ext.XTemplate',
                    '<tpl for=".">',
                    '{screenName}',
                    '</tpl>'
                )
            }]
        }, {
            xtype: 'screenpropertieseditor',
            itemId: 'messagesEditor',
            margin: '25',
            header: true,
            frame: false,
            border: true,
            collectionName: 'messages',
            title: 'Messages'
        }]

        me.callParent(arguments);
    }
});

當用戶更改組合框中的值時,我想更新screenpropertieseditor類型視圖。

視圖控制器:

Ext.define('Configurator.controller.ScreenProperties', {
    extend: 'Ext.app.Controller',

    refs: [{
        ref: 'screenPropertiesPage',
        selector: 'screenpropertiespage'
    }, {
        ref: 'screenSelector',
        selector: 'screenpropertiespage combobox[itemId=screenSelector]'
    }, {
        ref: 'screenPropertiesMessagesEditor',
        selector: 'screenpropertieseditor[itemId=messagesEditor]'
    }, {
        ref: 'screenPropertiesPage',
        selector: 'screenpropertiespage'
    }],

    init: function (application) {
        var me = this;
        this.control({
            'screenpropertiespage combobox[itemId=screenSelector]': {
                change: this.screenPropertiesPageStoreHandler
            }
        });
    },

    screenPropertiesPageStoreHandler: function (thisObj, eOpts) {
        var messagesEditor = this.getScreenPropertiesMessagesEditor();
        var screenSelector = this.getScreenSelector();
        var screenSelected = screenSelector.getValue();
        //Screen tile store first time loading handling
        if (screenSelected === undefined) {
            screenSelected = screenSelector.getStore().getAt(0).data.screenName;
        }

        var selectedRecord = screenSelector.getStore().findRecord(
            'screenName',
            screenSelected, 0, false, false, true);
        if (selectedRecord != undefined) {
            Ext.apply(messagesEditor, {
                'screenName': screenSelected
            });
            try {
                messagesEditor.bindStore(selectedRecord.messages());
            } catch (e) {}
        }
    }
});

ScreenPropertiesPage將會伴隨着更多的額外字段。 我必須創建ScreenPropertiesPage的多個實例。 只要任何ScreenPropertiesPage視圖的組合框中的值發生更改,就會觸發Configurator.controller.ScreenProperties的screenPropertiesPageStoreHandler方法。 但是由於我的引用和控制器中的選擇器不合適,因此它始終引用第一個ScreenPropertiesPage視圖。

您需要知道Extjs中的Controllersingleton

但是您可以在您的情況下強制Controller使用ScreenProperties處理多個視圖實例。 這是通過將事件從特定的視圖實例發送到Controller來處理更復雜的邏輯來完成的。

在我舉個例子之前,您需要意識到,使用refs處理同一視圖的多個實例是錯誤的,因為它使用了以下代碼(它只是一個包裝器): Ext.ComponentQuery.query('yourComponent')[0]; 因此,從您的實例池來看,它是第一個。 因此,您需要擺脫控制器中的refs ,因為它不適用於同一視圖的多個實例。

好吧,讓這種情況發生並實現一種很好的方式來處理同一視圖/組件的多個實例。

您認為:

initComponent: function () {
        var me = this;
        this.items = [{
            xtype: 'container',
            componentCls: 'screenComboSelectorPanel',
            layout: {
                type: 'hbox',
                align: 'center',
                pack: 'center'
            },
            items: [{
                xtype: 'combo',
                store: Ext.create(
                    'Configurator.store.screenproperties.ScreenProperties'
                ),
                itemId: 'screenSelector',
                margin: 3,
                width: 400,
                listConfig: {
                    maxHeight: 200
                },
                fieldLabel: 'Screen Name',
                disabledCls: 'disabledBtn',
                disabled: me.getOverLayMode(),
                queryMode: 'local',
                emptyText: '-SELECT-',
                valueField: 'screenName',
                displayField: 'screenName',
                forceSelection: true,
                selectOnTab: true,
                autoSelect: true,
                height: 25,
                tpl: Ext.create('Ext.XTemplate',
                    '<tpl for=".">',
                    '<div class="x-boundlist-item comboContainer "><div class="rowExpanedrTextArea " style="">{screenName}   </div>{[this.isExpandable(xkey,parent,values,xindex)]}</div>',
                    '</tpl>'
                ),
                displayTpl: Ext.create('Ext.XTemplate',
                    '<tpl for=".">',
                    '{screenName}',
                    '</tpl>'
                ),
                listeners: {
                    change: function (cmp, newValue, oldValue) {
                       this.fireEvent('onCustomChange',cmp,newValue, oldValue)
                    },
                    scope: this
                }
            }]
        }

Controller - ScreenProperties您需要偵聽此事件並在視圖中處理組件的特定實例

init: function (application) {
    var me = this;
    this.listen({
        // We are using Controller event domain here
        controller: {
            // This selector matches any originating Controller
            '*': {      
                onCustomChange: 'onCustonChangeHandler'
            }
        }
    });
},
onCustonChangeHandler: function(componentInstance, newValue, oldValue) {
    //Your complex logic here.
    //componentInstance is the instance of actual component in particular view
}

這樣,您可以使用一個控制器處理同一視圖的多個實例,因為在視圖中創建的每個特定組件都是通過事件傳遞的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM