我如何设置数据在一个不相关的ViewModel

How do I set data in an unrelated ViewModel

本文关键字:一个 不相关 ViewModel 置数据      更新时间:2023-09-26

我有一个sign in process,我已经把它粗略地做成了一个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');
    }
});

我要做的是:

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

最后一项是我有问题的地方。

如果登录窗口是面板的子窗口,那么我可以通过ViewModel继承来设置它,但是因为我使用的是小部件显示,所以我不能通过面板的项配置来设置。

有正确的方法吗?

没关系,我想出来了。答案一直都在我的问题里:

如果登录窗口是面板的子窗口,那么我可以通过ViewModel继承来设置它,但是因为我使用的是小部件显示,所以我不能通过面板的项配置来设置。

让窗口成为面板的子窗口:

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

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

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:/