在ExtJs中使用MVC控制器处理ajax事件的正确方法是什么

时间:2013-10-21 23:39:24

标签: extjs

我们正在尝试构建一个简单的原型来使用ExtJs来使用我们的数据服务(也是为了同时学习ExtJ)。

在开发原型时(具有ExtJS的基础知识),我遇到了几个hickup。在发布问题之前,我想让您快速浏览以下内容。

以下是与服务交互的主类。我们希望确保在ajax通信期间屏蔽/取消屏蔽某些UI组件。

Ext.define('Sample.provider.SvcClient', {

TestConnectivity: function(prms){
    debugger;

    Ext.Ajax.on('beforerequest', function(conn,o,result) {
        prms.BeforeRequest(conn,o,result);
    });

    Ext.Ajax.on('requestcomplete',function(conn,o,result) {
        prms.RequestComplete(conn,o,result);
    });

    Ext.Ajax.on('requestexception',function(conn,o,result) {
        prms.RequestException(conn,o,result);
    });

    Ext.Ajax.request({
        url: prms.Url,
        method: prms.HttpMethod,
        headers: {
            'Authorization' : 'Basic ' + prms.Credentials
        },
        success: prms.Success,
        failure: prms.Failure,
        callback: prms.Callback
    });
}

});

我们开发了SvcClient的扩展,特别是为了帮助在ajax通信期间屏蔽控件:

Ext.define('Sample.util.ClientProxy', {

CtlToMask : null,

DoTestConnection: function(ctlToMask, callback, url, userName, pwd) {
    debugger;
    var proxy = this;
    proxy.CtlToMask = ctlToMask;

        var client = new Sample.provider.SvcClient();
        var params = {
            Url: url,
            HttpMethod: "GET",
            Credentials: Sample.util.Conversions.Base64.encode(userName + ":" + pwd),
            CtlToMask: proxy.CtlToMask,
            Scope:proxy,
            BeforeRequest: function(conn,o,result,Scope) {
                debugger;
                if(Scope.CtlToMask !=null) {                        
                    if(Scope.CtlToMask.getEl() != undefined)
                        Scope.CtlToMask.getEl().mask('Testing Connectivity...', 'x-mask-loading');                    
                    else
                        Scope.CtlToMask.mask('Testing Connectivity...', 'x-mask-loading');                    
                }
            },                
            RequestComplete: function(conn,o,result) {
                if(this.CtlToMask !=null) {
                    if(this.CtlToMask.getEl() != undefined)
                        this.CtlToMask.getEl().unmask(true);                  
                    else
                        this.CtlToMask.unmask(true);                
                }                    
            },
            RequestException: function(conn,o,result) {
                if(this.CtlToMask !=null) {
                    if(this.CtlToMask.getEl() != undefined)
                        this.CtlToMask.getEl().unmask(true);                  
                    else
                        this.CtlToMask.unmask(true);                
                }
            }                                  
        };


        client.TestConnectivity(params);   

}

});

我的控制器如下所示:

Ext.define('Sample.controller.Locations', {
extend: 'Ext.app.Controller',

models: ['Location', 'Country'],

views: [
    'portal.location.Menu',
    'portal.location.Edit'
],

init: function() {
    this.control({
        'locationsMenu':{
            OpenAddNewSvcPopup: this.OnOpenAddNewSvcPopup
        },
        'locationsEdit':{
            TestSvcConnectivity: this.OnTestSvcConnectivity,
            render: function () { },
            afterrender: function () { },
            boxready: function () { }  
        }
    });
},

OnOpenAddNewSvcPopup: function(){       
    var newLoc = Ext.create('Sample.model.Location', {
        UserName: 'admin',
        Uri: 'http://localhost/DataServicesBase/Data.svc'
    });
    var v = Ext.create('widget.locationsEdit',{ mode:'add'});
    v.down('form').loadRecord(newLoc);
},

OnTestSvcConnectivity: function(ctl){

    var proxy = new Sample.util.ClientProxy();
    proxy.DoTestConnection(
        ctl,
        this.OnTestSvcConnectivityCallback,
        ctl.down("#Uri").value + '/Countries',
        ctl.down("#UserName").value,
        ctl.down("#Password").value
        );           
},

OnTestSvcConnectivityCallback: function(options,success,result){
    if(success) {
        //show the result
    }
    else {
             //Show error in window           
    }
}

});

视图如下所示:

Ext.define('Sample.view.portal.location.Edit', {
extend: 'Ext.window.Window',
alias: 'widget.locationsEdit',

//title: 'Edit Service Location',
layout: 'fit',
autoShow: true,
title: 'Edit Service Location',
bodyStyle: 'border:0px',
closeAction:'destroy',

config:{        
    mode: 'edit'
},

constructor: function(configs){
    this.callParent(arguments);        
    this.initConfig(configs);
    if(this.mode == "add") this.setTitle('Add New Service Location');
},

initComponent: function() {

    this.items = [
        {
            xtype: 'form',                
            items: [
                {
                    xtype:          'textfield',
                    name:           'Id',
                    itemId:         'Id',
                    fieldLabel:     'Unique Name',
                    labelStyle:     'font-weight:bold',
                    allowBlank:     false,
                    maxLength:      64,
                    width:          300
                },
                {
                    xtype:          'textfield',
                    name :          'Uri',
                    itemId:         'Uri',
                    fieldLabel:     'URI',
                    maxLength:      300,
                    width:          500,
                    allowBlank:     false
                },
                {
                    xtype:          'textfield',
                    name :          'UserName',
                    itemId:         'UserName',
                    fieldLabel:     'User Name',
                    allowBlank:     false,
                    maxLength:      64,
                    width:          200
                },
                {
                    xtype:          'textfield',
                    name :          'Password',
                    itemId:         'Password',
                    fieldLabel:     'Password',
                    allowBlank:     false,
                    maxLength:      64,
                    width:          200
                }                    
            ],
            bodyStyle: 'padding:5px;'
        }
    ];

    this.buttons = [
        {
            text:       'Test Connectivity',
            action:     'test',
            scope:      this,
            handler:    this.OnTestSvcConnectivity
        },
        {
            text:       'Save',
            action:     'save'
        },
        {
            text:       'Cancel',
            scope:      this,
            handler:    this.close
        }
    ];

    this.callParent();
    this.addEvents('TestSvcConnectivity') //custom event
},

OnTestSvcConnectivity: function(){
    this.fireEvent('TestSvcConnectivity', this); //will be raised to controller
}

});

Q1

这种方法在我第一次点击"测试连接"按钮(来自弹出窗口)。如果我第二次单击相同的按钮,(BeforeRequest)处理程序将触发两次。第三次单击,处理程序被激活三次。我的代码中有什么错误。

Q2

如果我取消弹出窗口并再次单击"测试连接"它永远不会奏效。处理程序仍然保持"一些"上一个弹出窗口实例的引用(或状态)。由于无法找到,它会抛出" undefine"对象成员。我通过调试器确认了这一点,我可以看到前一个弹出窗口实例的id而不是当前的id。处理程序总是试图尊重第一个实例化的弹出窗口,无论如何。

Q3

我们为此示例原型试图遵循的模式是否存在任何陷阱/问题。我们正在尝试使用ExtJS的MVC功能进行开发,并确保我们使用支持和良好的模式/实践,这样我们就不会遇到上述非常基​​本的问题。

0 个答案:

没有答案