zoukankan      html  css  js  c++  java
  • ext下的组建,mvc,mvvm

      组建和架构的包括固定的写法,风格还有规范,通过一个栗子(仅包含一个grid和点击事件),来描述extjs下的mvc和mvvm的整体结果

    组建化

    <!DOCTYPE HTML>
    <html manifest="">
    
    <head>
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta charset="UTF-8">
        <title>htjy</title>
        <link type="text/css" rel="stylesheet" href="css/font-awesome.css">
        <!-- The line below must be kept intact for Sencha Cmd to build your application -->
        <script type="text/javascript" src="/ext/build/ext.js"></script>
        <script type="text/javascript" src="/ext/build/ext-all.js"></script>
        <script src="/ext/packages/ext-locale/build/ext-locale-zh_CN.js"></script>
        <link href="/ext/packages/ext-theme-crisp/build/resources/ext-theme-crisp-all.css" rel="stylesheet" />
    </head>
    
    <body></body>
    <script>
    Ext.onReady(function() {
        //模型描述
        Ext.define('User', {
            extend: 'Ext.data.Model',
            fields: [{
                name: 'firstName',
                type: 'string'
            }, {
                name: 'lastName',
                type: 'string'
            }, {
                name: 'age',
                type: 'int'
            }, {
                name: 'eyeColor',
                type: 'string'
            }]
        });
    
        //仓库整合
        Ext.define('UserStore', {
            extend: 'Ext.data.Store',
            model: "User",
            data: [{
                firstName: 'Ed',
                lastName: 'Spencer'
            }, {
                firstName: 'Tommy',
                lastName: 'Maintz'
            }, {
                firstName: 'Aaron',
                lastName: 'Conran'
            }, {
                firstName: 'Jamie',
                lastName: 'Avins'
            }]
        });
    
        var store = Ext.create('UserStore');
    
        Ext.create('Ext.grid.Panel', {
            title: 'Simpsons',
            store: store,
            columns: [{
                text: 'firstName',
                dataIndex: 'firstName'
            }, {
                text: 'lastName',
                dataIndex: 'lastName'
            }, {
                text: 'age',
                dataIndex: 'age'
            }, {
                text: 'eyeColor',
                dataIndex: 'eyeColor'
            }],
            listeners: {
                itemclick: function() {
                    console.log('click el2');
                }
            },
            height: 200,
             400,
            renderTo: Ext.getBody()
        });
    
    
    });
    </script>
    
    </html>

    通过Sencha初始化+一个栗子的代码,虽然这养完成了任务,但只用到了组建,还没有用到更为重要的框架

    mvc

    跟着网上的呆毛,不明觉厉的使用方式

    model:

    Ext.define('app.model.User', {
        extend: 'Ext.data.Model',
        fields: [{
            name: 'firstName',
            type: 'string'
        }, {
            name: 'lastName',
            type: 'string'
        }, {
            name: 'age',
            type: 'int'
        }, {
            name: 'eyeColor',
            type: 'string'
        }]
    });

    controller:

    Ext.define('app.controller.User', {
        extend: 'Ext.app.Controller',
        init: function() {
            this.control({
                'userlist': {
                    itemclick: this.userlistHighlight
                }
            });
        },
        userlistHighlight: function() {
            console.log('click el');
        }
    });

    view:

    Ext.define("app.view.user.List", {
        extend: "Ext.grid.Panel",
        alias: 'widget.userlist',
        store: Ext.create('app.store.User'),
        columns: [{
            text: 'firstName',
            dataIndex: 'firstName'
        }, {
            text: 'lastName',
            dataIndex: 'lastName'
        }, {
            text: 'age',
            dataIndex: 'age'
        }, {
            text: 'eyeColor',
            dataIndex: 'eyeColor'
        }]
    });

    Viewport:单页面入口

    Ext.define("app.view.Viewport", {
        extend: "Ext.container.Viewport",
        layout: "fit",
        uses:['app.view.user.List','app.controller.User'],
        items: {
            xtype:"userlist"
        }
    });

    Application:架构启动

    Ext.define('app.Application', {
        extend: 'Ext.app.Application',
        name: 'app',
        stores: [
            // TODO: add global / shared stores here
        ],
        controllers: ['User'],
        autoCreateViewport: true,
        launch: function() {}
    });

    通过Sencha初始化+上面的代码,就可以正确的运行了,混合了配置信息和异步加载信息等多种方式,组建的使用错误不大,但是架构的使用,略微蛋疼

    1.uses是什么鬼?

    一次性将所有js文件全部加载绝不是一个好主意,延迟加载/按需加载也就逐步转换为架构的一部分,而user与requires就是依赖元素(其中加载器中的require方法-.-毕竟干的都是一件事)

    requires:初始化依赖文件,

    uses:业务(初始化后)依赖文件

            createOverride: function (className, data, createdFn) {
                var me = this,
                    overriddenClassName = data.override,
                    requires = data.requires,
                    uses = data.uses,
                    mixins = data.mixins,
                    mixinsIsArray,
                    compat = data.compatibility,
                    depedenciesLoaded,
                    classReady = function () {
                        var cls, dependencies, i, key, temp;
    
                        if (!depedenciesLoaded) {
                            dependencies = requires ? requires.slice(0) : [];
    
                            if (mixins) {
                                if (!(mixinsIsArray = mixins instanceof Array)) {
                                    for (key in mixins) {
                                        if (Ext.isString(cls = mixins[key])) {
                                            dependencies.push(cls);
                                        }
                                    }
                                } else {
                                    for (i = 0, temp = mixins.length; i < temp; ++i) {
                                        if (Ext.isString(cls = mixins[i])) {
                                            dependencies.push(cls);
                                        }
                                    }
                                }
                            }
    
                            depedenciesLoaded = true;
                            if (dependencies.length) {
                                // Since the override is going to be used (its target class is
                                // now created), we need to fetch the required classes for the
                                // override and call us back once they are loaded:
                                Ext.require(dependencies, classReady);
                                return;
                            }
                            // else we have no dependencies, so proceed
                        }
    
                        // transform mixin class names into class references, This
                        // loop can handle both the array and object forms of
                        // mixin definitions
                        if (mixinsIsArray) {
                            for (i = 0, temp = mixins.length; i < temp; ++i) {
                                if (Ext.isString(cls = mixins[i])) {
                                    mixins[i] = Ext.ClassManager.get(cls);
                                }
                            }
                        } else if (mixins) {
                            for (key in mixins) {
                                if (Ext.isString(cls = mixins[key])) {
                                    mixins[key] = Ext.ClassManager.get(cls);
                                }
                            }
                        }
    
                        // The target class and the required classes for this override are
                        // ready, so we can apply the override now:
                        cls = me.get(overriddenClassName);
    
                        // We don't want to apply these:
                        delete data.override;
                        delete data.compatibility;
                        delete data.requires;
                        delete data.uses;
    
                        Ext.override(cls, data);
    
                        // This pushes the overridding file itself into Ext.Loader.history
                        // Hence if the target class never exists, the overriding file will
                        // never be included in the build.
                        me.triggerCreated(className);
    
                        if (uses) {
                            // This "hides" from the Cmd auto-dependency scanner since
                            // the reference is circular (Loader requires us).
                            Ext['Loader'].addUsedClasses(uses); // get these classes too!
                        }
    
                        if (createdFn) {
                            createdFn.call(cls, cls); // last but not least!
                        }
                    };
    
                me.triggerExists(className, 2);
    
                if (!compat || Ext.checkVersion(compat)) {
                    // Override the target class right after it's created
                    me.onCreated(classReady, me, overriddenClassName);
                }
    
                return me;
            }

     requires属性下的js直接被加载,而uses下的js被加入usedclass方法,用以初始化完成后在加载

    2.store: Ext.create('app.store.User')是什么鬼?

     创建/配置`仓库`,grid非常依赖的实例,很显然,creat代表着创建,每次加载grid都会创建一个store在内存中...为了达到复用目的(类似于create,show),可以使用StoreManage进行管理

    3.Viewport

    domcument.body的封装,代表整个浏览界面(body,所有没有renderto),主要用于方便布局,一个页面只有一个viewport

    4.Application

    应用程序的封装(类似于路由的全局封装),包含了应用程序应该绑定的Models、Views和Controllers,可以通过响应的属性进行管理(其实等价于requires),其中view可以被Controller管理(controller的效果依赖view的存在),所以这个地方需要描述Models和Controllers

    当然了,application的配置又回在初始化时提前加载,所以是在view中使用requires分散压力,还是一口气配置完成,就看需求了

    修改后标准的mvc:

    Application:应用程序关联设置

    Ext.define('app.Application', {
        extend: 'Ext.app.Application',
        name: 'app',
        stores: ['User'],
        controllers: ['User'],
        models:['User'],
        autoCreateViewport: true,
        launch: function() {}
    });

    viewreport:body的封装,无需在引用

    Ext.define("app.view.Viewport", {
        extend: "Ext.container.Viewport",
        layout: "fit",
        items: {
            xtype:"userlist"
        }
    });

    view:真正的视图,完全找不到业务逻辑,如果页面需要修改,在此处

    Ext.define("app.view.user.List", {
        extend: "Ext.grid.Panel",
        alias: 'widget.userlist',
        store: 'User',
        columns: [{
            text: 'firstName',
            dataIndex: 'firstName'
        }, {
            text: 'lastName',
            dataIndex: 'lastName'
        }, {
            text: 'age',
            dataIndex: 'age'
        }, {
            text: 'eyeColor',
            dataIndex: 'eyeColor'
        }],
        initComponent: function() {
            this.callParent();
        }
    });

    controller:真正的逻辑层,可以通过他来关联views(原因你懂得,实践胜于理论),如果逻辑出错,就在这里,依赖选择器

    Ext.define('app.controller.User', {
        extend: 'Ext.app.Controller',
        views:['user.List'],
        init: function() {
            this.control({
                'userlist': {
                    itemclick: this.userlistHighlight
                }
            });
        },
        userlistHighlight: function() {
            console.log('click el');
        }
    });

    至此mvc的方式就已经完成了,尽管聊过延迟加载,其实在mvc模式下,延迟加载的解决方案相当的糟糕-。-

    mvvm

    根据官网的呆毛,进行尝试

    Application:应用程序关联设置

    Ext.application({
        name: 'app',
        extend: 'app.Application',
        autoCreateViewport:'app.view.main.Main'
    
    });

    view容器:view木有任何逻辑,但参与调用/绑定的设计,以减少工作量,此处有迷之`main`参数,木有加载配置

    Ext.define('app.view.main.Main', {
        extend: 'Ext.container.Container',
        xtype: 'app-main',
        controller: 'main',
        viewModel: {
            type: 'main'
        },
        layout: {
            type: 'border'
        },
    
        items: [{
            xtype: 'panel',
            bind: {
                title: '{name}'
            },
            region: 'west',
            html: '<ul><li>This area is commonly used for navigation, for example, using a "tree" component.</li></ul>',
             250,
            split: true,
            tbar: [{
                text: 'Button',
                handler: 'onClickButton'
            }]
        },{
            region: 'center',
            xtype: 'tabpanel',
            items:[{
                title: 'Tab 1',
                html: '<h2>Content appropriate for the current navigation.</h2>'
            }]
        }]
    });

    controller:所有的逻辑都在这里,我们可以将alias注释掉,做几个小测试

    Ext.define('app.view.main.MainController', {
        extend: 'Ext.app.ViewController',
    
        requires: [
            'Ext.window.MessageBox'
        ],
    
        // alias: 'controller.main',
    
        onClickButton: function () {
            Ext.Msg.confirm('Confirm', 'Are you sure?', 'onConfirm', this);
        },
    
        onConfirm: function (choice) {
            if (choice === 'yes') {
                //
            }
        }
    });

    vm:静态数据,此处可以添加各种get方法用以修改数据转换的逻辑

    Ext.define('app.view.main.MainModel', {
        extend: 'Ext.app.ViewModel',
    
        // alias: 'viewmodel.main',
    
        data: {
            name: 'app'
        }
    
        //TODO - add data, formulas and/or methods to support your view
    });

    总之,vm+c分散了业务的代码

    以上是官网的呆毛,如果根据这种格式去写第二个栗子就会发现,完全运行不起来。。。八层是该类未被加载的意思,但是,官网的例子又是为毛...

    bootstrap.json-->可以在该文件下看见一下内容

            "app.view.main.MainController": {
                "idx": 17,
                "alias": ["controller.main"],
                "alternates": []
            },
            "app.view.main.MainModel": {
                "idx": 18,
                "alias": ["viewmodel.main"],
                "alternates": []
            }

    在这里增加自己的测试项目,就可以相关像官网一样实现了

    以上为ext下的mvvm实现,感觉也就是mvc+双向绑定,不如angular这种舒服

  • 相关阅读:
    变量声明和定义的关系
    STL之Vector
    STL之顺序容器
    类成员函数可以为回调函数吗
    排序
    名字查找
    Java 写 Log
    Spring 框架中注释驱动的事件监听器详解
    Centos7 安装gitLab
    世界经济史是一部基于假象和谎言的连续剧
  • 原文地址:https://www.cnblogs.com/liuCy/p/4949561.html
Copyright © 2011-2022 走看看