zoukankan      html  css  js  c++  java
  • Backbone vs Ext JS 4 MVC

    导读

    最近一段时间,我在研究移动WebApp应用开发,想在设计WebApp前端JS构架时,使用MVC分层技术,经过一段时间的技术选型,最终确定使用Backbone JS作为底层基础MVC框架。在使用Backbone写示例时,总是觉得非常怪,但又说不出怪在哪,所以,就想通过Backbone与Ext JS 4 MVC的对比,来发现Backbone的缺点与优化点。PS:由于我在做Desktop前端JS开发时,十分青睐Ext JS这一类的框架,Ext JS 4 MVC是我认为在所有框架中做得最好的。

    特性对比

    在对比两个MVC框架之前,必须理解四个十分重要的特性:

    • UI Bindings:[UI 绑定] 我想说的不仅仅是模板,而是想谈一种在底层模型出现变化时,视图层能够自动刷新的方法。一旦您用过了支持 UI Binding 的框架(例如Ext)就很难放手回头了。
    • Composed Views:[组件化视图] 与所有的软件开发者一样,我也喜欢编写模块化、可重用的代码。基于这样的原因,当给 UI 编程的时候,我喜欢使用视图的方法来开发(个人更偏好在模板层时使用),当然这样也就需要拥有足够丰富的视图组件来支持。
    • Web Presentation Layer:[web 表示层] 我们在编写 web 程序时想要 Native 风格的组件,但是也没有理由来为一个 web 框架来创建它自己的布局管理器。HTML 和 CSS 是目前解决样式与布局的最好的方法,框架也应该以这一点为核心。
    • Play Nicely With Others:[兼容,友好] 不得不承认jQuery是十分犀利的。我不喜欢那种绑定着一个定制的jQuery副本的框架,而推荐直接使用jQuery。

    下面是两个框架对于四种特性支持程度的对比

    实例对比

    咱们先看一个简单的小例子,分别使用Ext JS与Backbone实现。这个例子也是Ext JS 4官方源码中的一个例子,参见http://dev.sencha.com/deploy/ext-4.1.0-gpl/examples/app/simple/simple.html

    对Ext JS 4 MVC不熟悉的同学,可以阅读文章ExtJS 4 MVC架构讲解,这篇文章对Ext JS 4 MVC讲解得很透彻。

    Ext JS 4 MVC例子

    1、目录结构。


    2、定义Application。你可以把app当作是一个应用入口,app包含应用的全局配置,同时也负责维护模型、视图、控制器的引用。Ext.app.Application本身也是继承自Ext.app.Controller,具体参见源码与官方文档。

    Ext.application({
        name: 'AM',
    
        // automatically create an instance of AM.view.Viewport
        autoCreateViewport: true,
    
        controllers: [
            'Users'
        ]
    }); 


    3、定义Viewport。Viewport中定义了app被加载时的初始视图。

    Ext.define('AM.view.Viewport', {
        extend: 'Ext.container.Viewport',
    
        layout: 'fit',
        items: [{
            xtype: 'userlist'
        }]
    });

     
    4、定义控制器。Controller是Model与View的粘合剂,Controller的control()函数使用ComponentQuery表达式设置组件视图的事件监听,这样就很好的将视图的控制逻辑与View本身分离,达到View重用的目的,当View是由组件构成时,组件的重用就显得很重要。不熟悉ComponentQuery请参见官方文档。

    Ext.define('AM.controller.Users', {
        extend: 'Ext.app.Controller',
    
        stores: ['Users'],
    
        models: ['User'],
    
        views: ['user.Edit', 'user.List'],
    
        refs: [
            {
                ref: 'usersPanel',
                selector: 'panel'
            }
        ],
    
        init: function() {
            this.control({
                'viewport > userlist dataview': {
                    itemdblclick: this.editUser
                },
                'useredit button[action=save]': {
                    click: this.updateUser
                }
            });
        },
    
        editUser: function(grid, record) {
            var edit = Ext.create('AM.view.user.Edit').show();
    
            edit.down('form').loadRecord(record);
        },
    
        updateUser: function(button) {
            var win    = button.up('window'),
                form   = win.down('form'),
                record = form.getRecord(),
                values = form.getValues();
    
            record.set(values);
            win.close();
            this.getUsersStore().sync();
        }
    });

     
    5、Model和View。在此略过代码部分,对于不熟悉Ext的同学,参见官方的源码及例子。Ext JS的Model、Store和View实现了UI Binding,当Model数据发生变化时自动完成View刷新。在上面的例子中,有一行代码record.set(values);,Record就是一个Model实例,当record被赋值时视图被刷新,这部分代码在ExtJS 4 MVC架构讲解文中有详细描述。

    Backbone MVC例子

    1、定义Model。Backbone的Model与Ext Model差不多,但是,Ext Model支持对象依赖关联,这个在特性复杂的企业应用中会比较有用,文章末尾会详细的解释对象依赖关联。Collection与Ext Store在概念上相似,但是,Collection仅仅是一个集合,而Store则是Ext非常重要的一个功能,它是Ext实现数据交互的重要中间件,功能非常强大,有兴趣的同学可以翻阅官方文档。

    var User = Backbone.Model.extend({
        idAttribute: 'id',
        url: '../testdata'
    });
    
    var uer = new User();
    
    var UserList = Backbone.Collection.extend({
        url: '../testdata',
        model: User
    });
    
    var users = new UserList();

     
    2、定义View。Backbone的View可以结合JS模版引擎实现视图渲染,视图事件控制使用事件委托的方式,例子中,el对象绑定一个委托click事件,当点击tr时调用函数showProfile,具体View事件请参见Backbone官方源码。视图控制事件监听应该出现在Controller中,由于Backbone没有Controller的概念,所以视图控制事件监听在View中实现,与视图渲染混在一起,导致视图无法重用,没有达到MVC分层的目的。现在,我们换一种思路思考,把Backbone View看作是一个Controller,View仅仅使用是一个HTML模版,虽然有点牵强,但视乎也是MVC。Backbone在早期的版本是有Controller这个类,但在新版本将Controller重命名成Router,我想Backbone作者也意识到了这个问题的存在吧!

    var HomeView = Backbone.View.extend({
        el: $('#mainview'),
    
        events: {
            'click tr': 'showProfile'
        },
    
        showList: function() {
            var html = ['<table>'];
            users.each(function(uer) {
                html.push('<tr>');
                html.push('<td>', uer.get('firstname'), '</td>');
                html.push('<td>', uer.get('lastname'), '</td>');
                html.push('</tr>');
            });
            html.push('</table>');
            this.$el.html(html.join(''));
        },
    
        showProfile: function() {
            this.$el.html('Hello, ' + uer.get('firstname') + ' ' + uer.get('lastname'));
        }
    });
    
    var home = new HomeView();

     
    3、定义Router。Router是个好东西,可以监听地址栏hash改变,实现页面跳转的控制逻辑。这视乎和Controller有点关系,但又能不说Router是Controller,这也是Controller重命名成Router的一个原因。

    var AppRouter = Backbone.Router.extend({
        routes: {
            'list': 'list',
            'profile/:id': 'getProfile'
        },
    
        getProfile: function(id) {
            uer.set('id', id);
            uer.fetch({
                type: 'POST',
                data: {
                    id: id
                },
                success: function() {
                    home.showProfile();
                }
            });
        },
    
        list: function() {
            users.fetch({
                type: 'POST',
                success: function() {
                    home.showList();
                }
            });
        }
    });
    
    new AppRouter();
    
    Backbone.history.start();  

    总结

    Ext JS 4 MVC是我认为非常完美的MVC框架之一,但是太依赖Ext的体系,很难从体系中剥离出来。


    Backbone JS优点、缺点都比较明显:

    • 优点:小巧、轻便可以很容易的集成到应用中,Backbone MVC可以适用大部分的项目需求。
    • 缺点:Backbone是MVC的不完整实现,只实现了部分,功能比较弱。

    我会考虑增加一些Backbone的功能,如Collection和Model的离线缓存,UI绑定数据改变自动渲染,在业务层封装出类似Ext的MVC,模版与组件化是视图渲染的两种主要方式。

    扩展阅读------对象依赖关联

    一个Model对象与其他Model对象存在依赖关系。定义两个Model:User、Post,User与Post的关系是一对多。
    服务端响应JSON格式:

    {
        id: 'user1',
        posts: [{
            id: 'post1',
            user_id: 'user1',
        }, {
            id: 'post2',
            user_id: 'user1',
        }, {
            id: 'post3',
            user_id: 'user1',
        }]
    }

     
    使用Ext JS 4定义Model:

    Ext.define('Post', {
        extend: 'Ext.data.Model',
        fields: ['id', 'user_id'],
        belongsTo: 'User'
    });
    
    Ext.define('User', {
        extend: 'Ext.data.Model',
        fields: ['id'],
        hasMany: {model: 'Post', name: 'posts'}
    });

     
    数据访问:

    User.load('user1', {
        success: function(user){
            user.posts().each(function(rec){
                console.log(rec.get('id'));
            });
        }
    });

    参考资料

    原创文章,转载请注明出处http://www.cnblogs.com/zhangdaiping
  • 相关阅读:
    “XXXXX” is damaged and can’t be opened. You should move it to the Trash 解决方案
    深入浅出 eBPF 安全项目 Tracee
    Unity3d开发的知名大型游戏案例
    Unity 3D 拥有强大的编辑界面
    Unity 3D物理引擎详解
    Unity 3D图形用户界面及常用控件
    Unity 3D的视图与相应的基础操作方法
    Unity Technologies 公司开发的三维游戏制作引擎——Unity 3D
    重学计算机
    windows cmd用户操作,添加,设备管理员组,允许修改密码
  • 原文地址:https://www.cnblogs.com/zhangdaiping/p/3055132.html
Copyright © 2011-2022 走看看