如何在不相关的ViewModel

时间:2015-08-07 20:50:11

标签: javascript extjs mvvm extjs5 extjs6

我有一个登录过程I've roughed into a fiddle(我在第110行开始停留的部分)。

这是代码的副本:

Ext.define('MyApp.MyPanel',{
    extend: 'Ext.panel.Panel',
    title: 'My App',
    controller: 'mypanelcontroller',
    viewModel: {
        data:{
            email: 'Not signed in'
        }  
    },
    width: 500,
    height: 200,
    renderTo: Ext.getBody(),

    bind:{
        html: "Logged in as: <b>{email}</b>"        
    },

    buttons:[
        {
            text: 'Sign in',
            handler: 'showSignInWindow'
        }
    ]
});

Ext.define('MyApp.MyPanelController',{
    extend: 'Ext.app.ViewController',
    alias: 'controller.mypanelcontroller',

    showSignInWindow: function (b,e,eOpts){
        Ext.widget('signinwindow').show();
    }
});

Ext.define('MyApp.SignInWindow',{
    extend: 'Ext.window.Window',
    title: 'Sign in',
    controller: 'signincontroller',

    xtype: 'signinwindow',

    width: 400,
    title: 'Sign In',
    modal: true,
    layout: 'fit',

    items:[
        {
            xtype: 'form',
            reference: 'signinfields',
            layout: 'anchor',
            bodyPadding: 5,
            defaults: {
                anchor: '100%',
                xtype: 'textfield'
            },
            items:[
                {
                    fieldLabel: 'Email',
                    name: 'email',
                    allowBlank: false
                },
                {
                    fieldLabel: 'Password',
                    name: 'password',
                    allowBlank: false,
                    inputType: 'password'
                }
            ],
            buttons:[
                {
                    text: 'forgot password',
                    width: 120,
                    //handler: 'onForgotPassword'
                },
                '->',
                {
                    text: 'sign in',
                    width: 120,
                    handler: 'onSignIn'
                }
            ]
        }
    ]
});


Ext.define('MyApp.SignInController',{
    extend: 'Ext.app.ViewController',
    alias: 'controller.signincontroller',

    onSignIn: function (button, event, eOpts){
        var data = button.up('form').getValues();
        button.up('window').mask('Signing in...');

        Ext.Ajax.request({
            // sorry, I don't know how to fake an API response yet :/
            url: '/authenticate/login',
            jsonData: data,
            scope: this,
            success: function (response){

            var result = Ext.decode(response.responseText);


            if(result.loggedIn == true){


                /*
                This is where I need help. 
                From the sign in window, I would like to update the viewmodel in `MyApp.MyPanel` with the 
                email returned in the response. If the window was a child of MyPanel, I would be able to update 
                via the ViewModel inheritance, but I can't here because the window isn't part of the `items` config.
                */
                this.getViewModel().set('email', result.data[0].email);

                Ext.toast({
                    title: 'Sign in successful',
                    html: "You've been signed in.",
                    align: 't',
                    closable: true,
                    width: 300
                });

                button.up('window').destroy();
            } else {
                Ext.toast({
                    title: 'Sign in failed',
                    html: "You sign in failed: " + result.message,
                    closable: true,
                    width: 300,
                    align: 't'
                });
                button.up('window').unmask();
            }

            },
            failure: function (){
            // debugger;

            }
        })
    },


    onForgotPassword: function (){
        Ext.Ajax.request({
            url: '/authenticate/test',
            success: function (response){

            },
            failure: function (){
            }
        })
        // Ext.Msg.alert('trigger forgot password logic', "This is where you need to trigger the API to send the forgot email form. <br>Say something here about how you'll get an email");
    }
});

Ext.application({
    name : 'Fiddle',

    launch : function() {
        Ext.create('MyApp.MyPanel');
    }
});

我想做的是:

  • 显示带有登录按钮的面板
  • 点击按钮显示登录窗口
  • 提交登录表单会尝试对服务器进行身份验证
  • 在成功验证后,用户的电子邮件在初始面板的ViewModel中设置

最后一颗子弹是我遇到的问题。

如果登录窗口是该面板的子级,那么我可以通过ViewModel继承来设置它,但是因为我使用小部件显示我无法通过面板设置回来items config。

有没有办法正确地做到这一点?

1 个答案:

答案 0 :(得分:0)

没关系,我明白了。答案一直都在我的问题中:

  

如果登录窗口是该面板的子项,那么我可以通过ViewModel继承设置它,但由于我使用的是widget显示,我无法通过面板的项目配置进行设置。

只需将窗口设为面板的子项:

Ext.define('MyApp.MyPanelController',{
    extend: 'Ext.app.ViewController',
    alias: 'controller.mypanelcontroller',

    showSignInWindow: function (b,e,eOpts){

        // Instead of creating the widget and showing it, create it and add it to the panel.
        // The window is going to float anyway, so being a child of the panel is no big deal

        var signinwindow = Ext.widget('signinwindow');
        this.getView().add(signinwindow).show();
    }
});

这样做意味着窗口继承了面板的viewmodel,你可以像这样设置viewmodel数据:

Ext.define('Registration.view.signin.SignInController', {
    extend: 'Ext.app.ViewController',
    alias: 'controller.signin-signin',

    onSignIn: function (button, event, eOpts){
        var data = button.up('form').getValues();
        button.up('window').mask('Signing in...');

        Ext.Ajax.request({
            url: '/authenticate/login',
            jsonData: data,
            scope: this,
            success: function (response){
            debugger;
            var result = Ext.decode(response.responseText);


            if(result.loggedIn == true){

                // Now that the window has inherited the panel's viewmodel
                // you can set it's data from the windows controller
                this.getViewModel().set('username', result.data[0].eMail);
            ...
emoji-for-exasperated:/