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

Javascript Extjs-如何从子视图控制器调用父视图控制器方法?,javascript,extjs,extjs6-modern,extjs6.5.1,Javascript,Extjs,Extjs6 Modern,Extjs6.5.1,我为弹出窗口中的按钮添加了侦听器onParentPagePopupCommit,该按钮在父视图控制器中声明并在视图端口中添加了弹出窗口,现在视图模型绑定按预期工作,但不确定如何调用父视图控制器方法而不在子视图控制器中公开相同的方法名称。在ExtJs Modern 6.5中,有没有办法在运行时扩展View Controller 为此,您需要在中使用config 例如: Ext.define('Person', { say: function(text) { alert(text); }

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

为此,您需要在中使用config

例如:

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

Ext.define('Developer', {
    extend: 'Person',
    say: function(text) { this.callParent(["print "+text]); }
});
在此中,我使用您的代码创建了一个演示,并进行了一些修改。我希望这将帮助或指导您实现您的要求

代码片段

 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'));
     }
 });
为此,您需要在中使用config

例如:

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

Ext.define('Developer', {
    extend: 'Person',
    say: function(text) { this.callParent(["print "+text]); }
});
在此中,我使用您的代码创建了一个演示,并进行了一些修改。我希望这将帮助或指导您实现您的要求

代码片段

 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'));
     }
 });

是的,我知道扩展pageViewController是可行的,但是如果扩展正确,viewModel绑定将不起作用。你的意思是像这样设置viewmodel“parent:pageVM”,并通过从pageViewController扩展来定义控制器。有没有办法从已经创建的类进行扩展,由于我需要访问父ctrler上的某些属性,因此在扩展它时调用此函数。getViewModel()返回popupVM而不是pageVM。@GowthamS您可以使用此
按钮.up('formpanel')。getViewModel()
而不是
此.getViewModel()
。我已经更新了我的答案,你也可以查看。这是个好主意。谢谢你的努力。。。我正在探索一些通用的方法,因为我不会手工编写这些东西所有的代码都是生成的(包括视图),所以对代码没有控制权。我必须为它制定正确的语法,以便代码生成器引擎能够完成它的任务……我期待着一些事情,比如将父/页viewModel n viewController重新用于弹出窗口?是的,我知道扩展pageViewController会起作用,但如果扩展正确,viewModel绑定将不起作用。你的意思是像这样设置viewmodel“parent:pageVM”,并通过从pageViewController扩展来定义控制器。有没有办法从已经创建的类进行扩展,由于我需要访问父ctrler上的某些属性,因此在扩展它时调用此函数。getViewModel()返回popupVM而不是pageVM。@GowthamS您可以使用此
按钮.up('formpanel')。getViewModel()
而不是
此.getViewModel()
。我已经更新了我的答案,你也可以查看。这是个好主意。谢谢你的努力。。。我正在探索一些通用的方法,因为我不会手工编写这些东西所有的代码都是生成的(包括视图),所以对代码没有控制权。我必须为它制定正确的语法,这样代码生成器引擎就可以完成它的任务了……我期待着一些事情,比如将父/页viewModel n viewController也用于popup?