zoukankan      html  css  js  c++  java
  • TodoMVC中的Backbone+MarionetteJS+RequireJS例子源码分析之一

    Marionette牵线木偶,Backbone是脊骨的意思,Marionette是基于Backbone做扩展库,可以理解为把脊骨骨架绑线扯着变成牵线木偶动起来哈哈,使backbone更易使用呵呵!

    构建或者扩展了很多新的东西,如:Application,Region,ItemView,CollectionView,CompositeView,LayoutView,AppRoute,Controller等等,把很多重复性的工作变成配置,程序入口引入了集中处理器Application,貌似Marionette的module不怎么好用,还不如用requireJS来得直观。

    一、文件目录

    文件目录

    比较清晰,bower_components里面存放jQuery,underscore等等依赖js库及js框架,不用管它;css文件也不用理它。

    一,主程序(/index.html-> js/main.js-> js/app.js ->js/routers/index.js & js/controllers/index.js)

    /index.html

    <!doctype html>
    <html lang="en" data-framework="marionettejs">
        <head>
            <meta charset="utf-8">
            <title>Backbone.Marionette & Requirejs • TodoMVC</title>
            <link rel="stylesheet" href="bower_components/todomvc-common/base.css">
            <link rel="stylesheet" href="css/custom.css">
        </head>
        <body>
            <section id="todoapp">
                <header id="header">
                </header>
                <section id="main">
                </section>
                <footer id="footer">
                </footer>
            </section>
            <footer id="info">
                <p>Double-click to edit a todo</p>
                <p>Created by <a href="http://github.com/jsoverson">Jarrod Overson</a></p>
            </footer>
            <script src="bower_components/todomvc-common/base.js"></script>
            <script data-main="js/main" src="bower_components/requirejs/require.js"></script><!--requireJS开始加载js/main.js文件-->
        </body>

    js/main.js

    require.config({//requireJS配置
        paths: {//路径配置
            underscore: '../bower_components/underscore/underscore',
            backbone: '../bower_components/backbone/backbone',
            marionette: '../bower_components/backbone.marionette/lib/backbone.marionette',
            jquery: '../bower_components/jquery/jquery',
            localStorage: '../bower_components/backbone.localStorage/backbone.localStorage',
            tpl: 'lib/tpl'
        },
        shim: {//非AMD规范库如backbone等库的配置,deps是依赖库,The shim config allows us to configure dependencies for scripts that do not call define() to register a module即下面的库不是通过define()来注册成为模块的
            underscore: {
                exports: '_'
            },
            backbone: {
                exports: 'Backbone',
                deps: ['jquery', 'underscore']
            },
            marionette: {
                exports: 'Backbone.Marionette',
                deps: ['backbone']
            }
        },
        deps: ['jquery', 'underscore']
    });
    
    require([
        'app',
        'backbone',
        'routers/index',
        'controllers/index'
    ], function (app, Backbone, Router, Controller) {  //requireJS标准写法
        'use strict';
    
        app.start();//应用启动-〉app.js
    
        new Router({ controller: Controller });//指定了Controller(controllers/index)的Marionette.AppRouter(routers/index;监视url传值触发相应的事件
    
        Backbone.history.start();//当你的所有路由创建并且设置完毕后,调用Backbone.history.start()来开始记录url的hash change,如果是html5还可以记录pushState等
    });

    js/app.js

    /*global define */
    
    define([
        'marionette',
        'collections/TodoList',
        'views/Header',
        'views/TodoListCompositeView',
        'views/Footer'
    ], function (Marionette, TodoList, Header, TodoListCompositeView, Footer) {//requireJS标准写法,其实就是用function里的变量去表示相应的库/模块的返回值(注意:根据requireJS规范,每个模块应该要有返回值,如app.js最后用了return window.app=app;)
        'use strict';
    
        var app = new Marionette.Application();
        //创建APP, Marionette官方描述为:the hub of your composite
    //application. It organizes, initializes and coordinates the various pieces of your app.
        var todoList = new TodoList();//collections/TodoList, collections就是model集
    
        var viewOptions = {
            collection: todoList
        };
    
        var header = new Header(viewOptions);
        var main = new TodoListCompositeView(viewOptions);
        var footer = new Footer(viewOptions);//这三个view都是绑定collections/TodoList这个collection
    
        app.addRegions({//给app增加region,region是分区处理更加灵活
            header: '#header',
            main: '#main',
            footer: '#footer'
        });
    
        app.addInitializer(function () {//添加事件到Marionette的初始器 app启动时会被马上执行
            //show 三个region
            app.header.show(header);
            app.main.show(main);
            app.footer.show(footer);
    
            todoList.fetch();//collection todoList获取localstorage的数据
        });
    
        app.listenTo(todoList, 'all', function () {//监听collection todoList 所有事件包括todoList.fetch();
            app.main.$el.toggle(todoList.length > 0);//main view执行toggle 函数
            app.footer.$el.toggle(todoList.length > 0);//footer view执行toggle 函数
        });
    
        app.vent.on('todoList:filter', function (filter) {//vent是用于定义供实例外部引用的函数,可以看见在controller里面trigger此函数
            footer.updateFilterSelection(filter);//执行footer view里面的函数
    
            document.getElementById('todoapp').className = 'filter-' + (filter === '' ? 'all' : filter);//纯js
        });
    
        app.vent.on('todoList:clear:completed', function () {//vent是用于定义供实例外部引用的函数,可以看见在footer view里面trigger此函数
            todoList.getCompleted().forEach(function (todo) {
                todo.destroy();
            });
        });
    
        return window.app = app;//把app绑到window全局对象并返回
    });

    js/routers/index.js

    /*global define */
    define([
        'marionette'
    ], function (Marionette) {
        'use strict';
    
        return Marionette.AppRouter.extend({
            appRoutes: {
                '*filter': 'setFilter'//*splat表示可以匹配任意数量的URL形式,如路由:file/*path -> file/a/b/c.txt,传递值为/a/b/c.txt;题外的如 :param将匹配斜杠/之间单一的一个URL变量,如路由:search/:query/p:page -> #search/obama/p2,传值为"obama"和"2"
            }
        });
    });

    js/controllers/index.js

    /*global define */
    define([
        'app'
    ], function (app) {
        'use strict';
    
        return {
            setFilter: function (param) {
                app.vent.trigger('todoList:filter', param && param.trim() || '');//根据URL中的传的值param触发app.js中定义的vent(todoList:filter)的函数
            }
        };
    });

     

  • 相关阅读:
    React 实践记录 02 Flux introduction
    React 实践记录 01 组件开发入门
    IntelliJ IDEA 2018.2.2及以下版本破解方法
    Icon.png pngcrush caught libpng error:Read
    MySQL导入.sql文件及常用命令
    MySql Host is blocked because of many connection errors; unblock with 'mysqladmin flush-hosts' 解决方法
    mysql 导出数据库命令
    MySQL 连接本地数据库、远程数据库命令
    在EC2上创建root用户,并使用root用户登录
    svn 批量添加命令
  • 原文地址:https://www.cnblogs.com/fastmover/p/4285155.html
Copyright © 2011-2022 走看看