Extjs - 如何从子视图控制器调用父视图控制器方法?

时间:2018-01-09 20:18:14

标签: javascript extjs extjs6-modern extjs6.5.1

我为弹出窗口中的按钮添加了一个监听器onParentPagePopupCommit,该按钮在父视图控制器中声明并在视图端口中添加了弹出窗口,现在视图模型绑定正在按预期工作,但不确定如何调用父视图控制器方法,而不在子视图控制器中公开相同的方法名称。有没有办法在运行时在ExtJs Modern 6.5中扩展View Controller。

Fiddle

onShowChildPopup: function (sender) {
         var popup = sender.up('panel').popups['childPopup'],
             pageCtrler = sender.lookupController(),
             pageVM = pageCtrler.getViewModel(),
             page = pageCtrler.getView(),
             popupCtrler = new Ext.app.ViewController({
                 parent: pageCtrler, //setting parent ctrler
                 //popup commit event on popup view controller
                 onPopupCommit: function () {
                     debugger;
                     Ext.Msg.alert("Popup Update", "Popup View Controller Invoked")
                     console.log("popup view controller - commit");
                 },

                 // this works but any other way
                 // same methods name on popup view ctrler...
                 /*onParentPagePopupCommit: function(){
                     debugger;
                     // I don't like this way of invoking a parent method
                     // this may introduce few more bugs if the parent gets value from its own
                     // view model - (this will be parent vm and not child/popup.)
                     // need something similar to extend inorder to reuse certain methods..
                     this.parent.onParentPagePopupCommit();

                     var vm = this.getViewModel().get('vm');
                     vm.set('fullName',this.getFullName());


                 }*/
             }),
             popupVM = new Ext.app.ViewModel({
                 parent: pageVM, //setting parent view model
                 links: {
                     //vm is not merging with parent
                     //vm: {

                     childvm: {
                         reference: 'ChildModel',
                         create: {
                             address: "child Address",
                             phone: "child Phone"
                         }
                     }
                 }
             });

         popup.controller = popupCtrler;
         popup.viewModel = popupVM;

         popup = Ext.create(popup);
         popup.setShowAnimation({
             type: 'slideIn',
             duration: 325,
             direction: 'up'
         });
         popup.setHideAnimation({
             type: 'slideOut',
             duration: 325,
             direction: 'down'
         });
         popup.setCentered(true);
         /* popup.on('show', function () {
              debugger;
          });*/
         Ext.Viewport.add(popup).show();
         //popup.showBy(page, "c-c");

     }

1 个答案:

答案 0 :(得分:2)

为此,您需要在extend中使用controller配置。

例如:

Ext.define('Person', {
    say: function(text) { alert(text); }
});

Ext.define('Developer', {
    extend: 'Person',
    say: function(text) { this.callParent(["print "+text]); }
});

FIDDLE 中,我使用您的代码创建了一个演示并进行了一些修改。我希望这有助于或指导您实现您的要求。

代码段

 Ext.define('ParentModel', {
     extend: 'Ext.data.Model',
     alias: 'model.parentmodel',
     fields: [{
         name: 'firstName',
         type: 'string'
     }, {
         name: 'lastName',
         type: 'string'
     }, {
         name: 'address',
         type: 'string'
     }]
 });

 Ext.define('ChildModel', {
     extend: 'Ext.data.Model',
     alias: 'model.childmodel',
     fields: [{
         name: 'address',
         type: 'string'
     }, {
         name: 'phone',
         type: 'number'
     }, {
         name: 'fullName',
         type: 'string'
     }]
 });

 Ext.define('PageViewModel', {
     extend: 'Ext.app.ViewModel',
     alias: 'viewmodel.pageviewmodel',
     links: {
         vm: {
             reference: 'ParentModel',
             create: {
                 firstName: 'firstName-ParentVM',
                 lastName: 'lastName-ParentVM'
             }
         }
     }
 });

 Ext.define('PageViewController', {
     extend: 'Ext.app.ViewController',
     alias: 'controller.pageviewcontroller',

     init: function () {
         this.callParent(arguments);
     },

     //i understand fullname can also be done on model using formula/conver
     //this is just a sample
     getFullName: function () {
         var vm = this.getViewModel().get('vm');
         return vm.get('firstName') + " " + vm.get('lastName');
     },

     //popup commit event on parent view controller
     onParentPagePopupCommit: function (button) {
         var vm = button.up('formpanel').getViewModel().get('vm');
         vm.commit();
         Ext.Msg.alert("Parent Page Update", "Parent View Controller Invoked");
         console.log("Page view controller - commit");
     },

     onShowChildPopup: function (button) {
         var popup = button.up('panel').popups['childPopup'],
             pageCtrler = button.lookupController(),
             pageVM = pageCtrler.getViewModel(),
             page = pageCtrler.getView(),
             popupVM = new Ext.app.ViewModel({
                 parent: pageVM, //setting parent ViewModel
                 links: {
                     //vm is not merging with parent
                     //vm: {
                     childvm: {
                         reference: 'ChildModel',
                         create: {
                             address: "child Address",
                             phone: "child Phone"
                         }
                     }
                 }
             });

         popup.viewModel = popupVM;
         popup = Ext.create(popup);
         popup.setShowAnimation({
             type: 'slideIn',
             duration: 325,
             direction: 'up'
         }).setHideAnimation({
             type: 'slideOut',
             duration: 325,
             direction: 'down'
         }).setCentered(true);
         Ext.Viewport.add(popup).show();
     }
 });

 //Need to extend popup controller from PageViewController(parent)
 Ext.define('PopupViewController', {
     extend: 'PageViewController',
     alias: 'controller.popupviewcontroller',
     //popup commit event on popup view controller
     onPopupCommit: function () {
         Ext.Msg.alert("Popup Update", "Popup View Controller Invoked")
         console.log("popup view controller - commit");
     }
 });

 Ext.define('MainPage', {
     extend: 'Ext.Panel',
     config: {
         title: 'Page',
         width: '100%',
         height: '100%',
         layout: {
             type: 'vbox',
             align: 'stretch'
         }
     },
     viewModel: {
         type: 'pageviewmodel'
     },
     controller: {
         type: 'pageviewcontroller'
     },
     width: '100%',
     height: '100%',
     popups: {
         childPopup: {
             xtype: 'formpanel',
             controller: 'popupviewcontroller',
             title: 'Cild Popup',
             floating: true,
             modal: true,
             hideonMaskTap: true,
             layout: 'float',
             minWidth: 300,
             maxHeight: 580,
             tools: [{
                 type: 'close',
                 handler: function () {
                     var me = this.up('formpanel');
                     me.hide();
                 }
             }],
             items: [{
                 xtype: 'container',
                 layout: {
                     type: 'vbox',
                     align: 'stretch',
                     pack: 'center'
                 },
                 items: [{
                     xtype: 'fieldset',
                     items: [{
                         xtype: 'label',
                         bind: {
                             html: '{vm.firstName} {vm.lastName}'
                         }

                     }, {
                         xtype: 'textfield',
                         label: 'First Name',
                         name: 'firstName',
                         bind: {
                             value: '{vm.firstName}'
                         }
                     }, {
                         xtype: 'textfield',
                         label: 'Last Name',
                         name: 'lastName',
                         bind: {
                             value: '{vm.lastName}'
                         }
                     }, {
                         xtype: 'textfield',
                         label: 'Last Name',
                         name: 'lastName',
                         bind: {
                             //value: '{vm.address}'
                             value: '{childvm.address}'
                         }
                     }]
                 }, {
                     xtype: 'container',
                     docked: 'bottom',
                     layout: 'hbox',
                     items: [{
                         xtype: 'button',
                         text: 'Popup Update',
                         handler: 'onPopupCommit'
                     }, {
                         xtype: 'button',
                         text: 'Parent Update',
                         handler: 'onParentPagePopupCommit'
                     }]
                 }]
             }]
         }
     },
     bodyPadding: 10,
     items: [{
         xtype: 'fieldset',
         title: 'Enter your name',
         items: [{
             xtype: 'textfield',
             label: 'First Name',
             name: 'firstName',
             bind: {
                 value: '{vm.firstName}'
             }
         }, {
             xtype: 'textfield',
             label: 'Last Name',
             name: 'lastName',
             bind: {
                 value: '{vm.lastName}'
             }
         }]
     }, {
         xtype: 'button',
         text: 'Show Popup',
         handler: 'onShowChildPopup'
     }]
 });

 Ext.application({
     name: 'Fiddle',
     launch: function () {
         Ext.Viewport.add(Ext.create('MainPage'));
     }
 });