dispatcher - 模块调度器控件

当hash改变时,按需要载入一个模块并展示在网页上,模块调度器,可以根据hash的umi调度出相应的模块

Allocate

模块调度器的配置 nej.ut.$$Dispatcher$getInstance(_options) _options的配置如下:

_options = {
    rules:{
        rewrite:{
            '404':'/m/a/a0/',
            '/m/a/a0/':'/'
        },
        title:{
            '/m/b/':'Module B',
            '/m/c/':'Module C'
        }
    },
    modules:{
        '/':'index/ui.html',

        '/m':'index/m.html',
        '/m/a':'index/a.html',
        '/m/b/':'index/b.html',
        '/m/c/':'index/c.html',

        '/m/a/a0/':{module:'index/a.a0.html',title:'Module A-A0'},
        '/m/a/a1/':{module:'index/a.a1.html',title:'Module A-A1'},
        '/m/a/a2/':{module:'index/a.a2.html',title:'Module A-A2'},

        '/?/b/b0/':'index/b.b0.html',
        '/?/b/b1/':'index/b.b1.html',
        '/?/b/b2/':'index/b.b2.html'
    }
}

可以在初使化调度器时传入上面的配置,可以在_$registAll方法传入上面的配置数据。

rules.rewirte是url重写,但他不会更的改变hash地址上的hash,是模块的一个影射关系,上面404是指hahs为#404时调度的模块是/m/a/a0, hash为/m/a/a0时的模块是/。

title是给各模块指定一个title,module是hash和按需加载和页面的对应关系, 如当hash为/m时,先进行验证/m是否在配置过了,要是没有配置过,进行出错回调,如果已经存在于配置器,查看模块是否加载完成,如果没有加载完成,用iframe去加载html ,html里页全是textarea,有css,jst,ntp,js等,加载完html后,进行textarea的parse,同时运行html里的脚本文件,然后就把脚本的运行权限交由加载进来的模块了,设置模块为已加载过。

由于调度器是按需加载进来,放在不同的html文件里,我们要调度三个模块,就需要有4个html文件,一个是框架html,三个是模块html 示例都是公有模块,实现的功能如下,当tab点击时tab下的内容按需加载内容

 模块调度

首选做框架的html,框架里包括tab节点和tab切换后内容显示节点,指出入口文件index.js,在这个脚本里进行调度器的配置工作

location.config指出模板文件所在目录

<!doctype html>
<html>
<head>
<meta charset="utf-8" />
<title>动画控件 - 前端实例</title>
<link href="../../../../css/template.css" rel="stylesheet" type="text/css" />
<link href="../../../../css/default.css" rel="stylesheet" type="text/css"/>
<link href="../../../../css/rainbow.css" rel="stylesheet" type="text/css"/>
<script src="../../../../js/highlight.pack.js"></script>
<style>
.cse{position:relative;height:250px;background: #474949;}
.cse-1{height:40px;padding-top:20px}
.center{background:#fff;height:6px;width:6px;overflow:hidden;border-radius:3px;position:absolute;top:150px;left:150px}
.ball{background:#fff;height:6px;width:6px;overflow:hidden;border-radius:6px;position:absolute;top:150px;left:50px}
.ball-1{top:20px}
.block{background:#ccc;width:50px;height:20px;overflow:hidden;margin-left:20px}
</style>
</head>
<body>
    <div class="g-doc">
        <div class="g-hd">
            <h1 class="m-logo">网易-杭研院-前端技术组-实例库</h1>
            <h2 class="m-title">tab控件</h2>
        </div>
        <div class="g-bd">
            <div class="g-mn">
                 <div class="m-tab">
                    <ul id="tab1">
                        <li><a href="#/m/a/">模块a</a></li>
                        <li><a href="#/m/b/">模块b</a></li>
                        <li><a href="#/m/c/">模块c</a></li>
                    </ul>
                </div>
                <div class="m-cnt" id="cnt"></div>
                <div class="m-event">
                    <h2>事件日志</h2>
                    <div class="panel">
                        <div class="client" id="log"></div>
                    </div>
                </div>
            </div>
        </div>
    </div>
    </div>
    <div class="g-bd">
        <div class="m-foot">
            如有任何问题,请联系:俞棋军(<a href="mailto:yuqijun@corp.netease.com">wqwei@corp.netease.com</a>)
        </div>
    </div>
    <div class="g-ft">
        <div class="m-foot">&nbsp;&copy;&nbsp;网易-杭研院-前端技术组</div>
    </div>
    <!-- @VERSION -->
    <script>
        location.config = {root:'./'};
    </script>
    <script src="http://192.168.144.11/libs/nej/src/define.js?pro=../"></script>
    <script src="../js/index.js"></script>
</body>
</html>

在入口文件里配置调度器:

var f = function(){
    var _  = NEJ.P,
        _e = _('nej.e'),
        _t = _('nej.ut'),
        _p = _('dm.m');

    window.dispatcher = _t._$$Dispatcher._$getInstance({
        rules:{
            rewrite:[
                {'/m/a/':'/m/'}, //重写规则,支持正则表达式,当模块是/m/时跳转到/m/a/,当hash是空是跳转到模块/m/a/
                {'/m/a/':''}
            ],
            title:{
                '/m/a/':'Module A',
                '/m/b/':'Module B',
                '/m/c/':'Module C'
            }
        },
        modules:{
            '/m/a/':'a.html',       //hash为/m/a/时加载a.html,后面的/是必须要加的
            '/m/b/':'b.html',       //hash为/m/b/时加载b.html,后面的/是必须要加的
            '/m/c/':'c.html',       //hash为/m/c/时加载c.html,后面的/是必须要加的
        }
    });
    _e._$parseTemplate('template-box');
    dispatcher._$active();          //启动hash检测定时器

    var _m = _p._$$ModuleM._$allocate();    //同步tab状态
    _m._$doSyncTab(location.href);
};
define(['{lib}util/template/tpl.js','{pro}js/m.js'
       ,'{lib}util/dispatcher/dispatcher.2.js'],f);

a.html模块的文件如下:

<meta charset="utf-8"/>
<!-- @TEMPLATE -->
<textarea name="css">
    .m-a1{min-height:500px;_height:500px;background:#fdc;}
    .m-a1 input{padding:5px 10px;margin:10px 0;}
</textarea>
<textarea name="ntp" id="a1-ntp-0">
    <div class="m-a1">
        <p>aaaaaaaaaaaaaaaaaaa</p>
        <p>aaaaaaaaaaaaaaaaaaa</p>
        <p>aaaaaaaaaaaaaaaaaaa</p>
        <p>aaaaaaaaaaaaaaaaaaa</p>
        <p>aaaaaaaaaaaaaaaaaaa</p>
        <p>aaaaaaaaaaaaaaaaaaa</p>
        <p>aaaaaaaaaaaaaaaaaaa</p>
    </div>
</textarea>
<textarea name="js" data-src="../js/a.js"></textarea>
<!-- /@TEMPLATE -->

a模块的文件入口是a.js如下:

/**
 * ------------------------------------------
 * 模块实现文件
 * @version  1.0
 * @author   genify(caijf@corp.netease.com)
 * ------------------------------------------
 */
var f = function(){
    // variable declaration
    var _  = NEJ.P,
        _e = _('nej.e'),
        _t = _('nej.ut'),
        _p = NEJ.P('dm.m'),
        _g = window,
        _proModuleA,
        _supModuleA;
    /**
     * 模块对象
     * @class   模块对象
     * @extends {dm.ut._$$Module}
     * @param   {Object} _options 可选配置参数,已处理参数列表如下所示
     *                           
     */
    _p._$$ModuleA = NEJ.C();
      _proModuleA = _p._$$ModuleA._$extend(_t._$$Module,!0);
      _supModuleA = _p._$$ModuleA._$supro;
    /**
     * 构建模块
     * @return {Void}
     */
    _proModuleA.__init = function(){
        this.__body = _e._$getNodeTemplate('a1-ntp-0');
        this.__supInit();
    };
    /**
     * 构建模块
     * @return {Void}
     */
    _proModuleA.__onShow = function(){
        var _parent = _e._$get('cnt'); 
        _parent.appendChild(this.__body);
        _supModuleA.__onShow.apply(this,arguments);
    };

    /**
     * 隐藏模块触发事件,子类实现具体逻辑
     * @return {Void}
     */
    _proModuleA.__onHide = function(_event){
        _e._$removeByEC(this.__body);
    };
    // notify loaded
    _g.dispatcher._$loaded('/m/a',_p._$$ModuleA);
};
define(
      ['{lib}util/dispatcher/module.2.js'],f);

b.html模块文件如下:

<meta charset="utf-8"/>
<!-- @TEMPLATE -->
<textarea name="css">
    .m-a1{min-height:500px;_height:500px;background:#fdc;}
    .m-a1 input{padding:5px 10px;margin:10px 0;}
</textarea>
<textarea name="ntp" id="b1-ntp-0">
    <div class="m-a1">
        <p>bbbbbbbbbbbbbbbbb</p>
        <p>bbbbbbbbbbbbbbbbb</p>
        <p>bbbbbbbbbbbbbbbbb</p>
        <p>bbbbbbbbbbbbbbbbb</p>
        <p>bbbbbbbbbbbbbbbbb</p>
        <p>bbbbbbbbbbbbbbbbb</p>
        <p>bbbbbbbbbbbbbbbbb</p>
    </div>
</textarea>
<textarea name="js" data-src="../js/b.js"></textarea>
<!-- /@TEMPLATE -->

b模块的文件入口是b.js如下:

/**
 * ------------------------------------------
 * 模块实现文件
 * @version  1.0
 * @author   genify(caijf@corp.netease.com)
 * ------------------------------------------
 */
var f = function(){
    // variable declaration
    var _  = NEJ.P,
        _e = _('nej.e'),
        _v = _('nej.v'),
        _u = _('nej.u'),
        _t = _('nej.ut'),
        _p = NEJ.P('dm.m'),
        _g = window,
        _proModuleB,
        _supModuleB;
    /**
     * 模块对象
     * @class   模块对象
     * @extends {dm.ut._$$Module}
     * @param   {Object} _options 可选配置参数,已处理参数列表如下所示
     *                           
     */
    _p._$$ModuleB = NEJ.C();
      _proModuleB = _p._$$ModuleB._$extend(_t._$$Module,!0);
      _supModuleB = _p._$$ModuleB._$supro;
      /**
       * 构建模块
       * @return {Void}
       */
      _proModuleB.__init = function(){
        this.__body = _e._$getNodeTemplate('b1-ntp-0');
        this.__supInit();
      };
      /**
       * 构建模块
       * @return {Void}
       */
      _proModuleB.__onShow = function(){
        var _parent = _e._$get('cnt'); 
        _parent.appendChild(this.__body);
        _supModuleB.__onShow.apply(this,arguments);
      };
      /**
       * 隐藏模块触发事件,子类实现具体逻辑
       * @return {Void}
       */
      _proModuleB.__onHide = function(_event){
          _e._$removeByEC(this.__body);
      };
    // notify loaded
    _g.dispatcher._$loaded('/m/b',_p._$$ModuleB);
};
define(['{lib}util/dispatcher/module.2.js'],f);

c.html模块文件如下:

<meta charset="utf-8"/>
<!-- @TEMPLATE -->
<textarea name="css">
    .m-a1{min-height:500px;_height:500px;background:#fdc;}
    .m-a1 input{padding:5px 10px;margin:10px 0;}
</textarea>
<textarea name="ntp" id="c1-ntp-0">
    <div class="m-a1">
        <p>ccccccccccccccccccccccc</p>
        <p>ccccccccccccccccccccccc</p>
        <p>ccccccccccccccccccccccc</p>
        <p>ccccccccccccccccccccccc</p>
        <p>ccccccccccccccccccccccc</p>
        <p>ccccccccccccccccccccccc</p>
        <p>ccccccccccccccccccccccc</p>
    </div>
</textarea>
<textarea name="js" data-src="../js/c.js"></textarea>
<!-- /@TEMPLATE -->

c模块的文件入口是c.js如下:

/**
 * ------------------------------------------
 * 模块实现文件
 * @version  1.0
 * @author   genify(caijf@corp.netease.com)
 * ------------------------------------------
 */
var f = function(){
    // variable declaration
    var _  = NEJ.P,
        _e = _('nej.e'),
        _v = _('nej.v'),
        _u = _('nej.u'),
        _t = _('nej.ut'),
        _p = NEJ.P('dm.m'),
        _g = window,
        _proModuleC,
        _supModuleC;
    /**
     * 模块对象
     * @class   模块对象
     * @extends {dm.ut._$$Module}
     * @param   {Object} _options 可选配置参数,已处理参数列表如下所示
     *                           
     */
    _p._$$ModuleC = NEJ.C();
      _proModuleC = _p._$$ModuleC._$extend(_t._$$Module,!0);
      _supModuleC = _p._$$ModuleC._$supro;
      /**
       * 构建模块
       * @return {Void}
       */
      _proModuleC.__init = function(){
        this.__body = _e._$getNodeTemplate('c1-ntp-0');
        this.__supInit();
      };
      /**
       * 构建模块
       * @return {Void}
       */
      _proModuleC.__onShow = function(){
        var _parent = _e._$get('cnt'); 
        _parent.appendChild(this.__body);
        _supModuleC.__onShow.apply(this,arguments);
      };
      /**
       * 隐藏模块触发事件,子类实现具体逻辑
       * @return {Void}
       */
      _proModuleC.__onHide = function(_event){
          _e._$removeByEC(this.__body);
      };
    // notify loaded
    _g.dispatcher._$loaded('/m/c',_p._$$ModuleC);
};
define(['{lib}util/dispatcher/module.2.js'],f);

Explain

调度器配置:

// 取调度器实例 var dispatcher = nej.ut.$$Dispatcher.$getInstance();

// 添加规则 dispatcher._$rule({ title:{ '/m/a':'模块标题', '/m/b':'模块标题' }, rewrite:[ {'/m/a':''}, {'/m/b':/^\/m\/d.*$/i} ] });

// 注册模块 dispatcher._$regist({ '/m/a':'/m/a.html', '/m/b':'/m/b.html', '/m/c':'/m/c.html' });

// 激活调度器 dispatcher._$active();

cycler external interface

_$rule(_options);                     调置添加调度规则

// 配置模块标题
 dispatcher._$rule('title',{
     '/m/a':'模块标题',
     '/m/b':'模块标题',
     '/m/c':'模块标题'
 });

 // 配置与匹配顺序无关重写规则
 // 重写规则配置结构:{ 目标UMI:重写规则 }
 // 重写规则可以是字符串(全字符匹配)或者正则表达式
 dispatcher._$rule('rewrite',{
     '/m/b':/^\/m\/b.*$/i,
     '/m/c':'/m/d'
 });

 // 批量配置重写规则
 // 重写规则内置匹配代码支持
 // 404 - 当模块不存在时重定向的模块UMI
 dispatcher._$rule([
     {'/m/a':'/m/','/m/c':'/m/d'},  // <---- 此处两条规则匹配与顺序无关
     {'/m/b':/^\/m\/b.*$/i},
     {'404':'/m/a'}                 // <---- 模块不存在时定向到/m/a模块
 ]);

_$regist(_options);                                注册UMI与模块的对应关系
// 注册模块的模板文件路径
 dispatcher._$regist('/m/a/','/m/a.html');

 // 注册模块的配置信息,包括标题和文件路径
 dispatcher._$regist('/m/a/',{
     title:'模块标题',
     module:'/m/a.html'
 });

 // 注册模块的配置信息,包括标题和模块构造器
 dispatcher._$regist('/m/a/',{
     title:'模块标题',
     module:np.m._$$ModuleA
 });

 // 注册模块的构造器
 dispatcher._$regist('/m/a/',np.m._$$ModuleA);

 // 注册私有模块指定分组ID,同一分组的私有模块调度时仅显示一个模块
 dispatcher._$regist('/?/a/b/',{
     gid:'234567890',
     module:'/m/a/b.html'
 });

 // 批量注册模块
 dispatcher._$regist({
     '/m/a/':'/m/a.html',
     '/m/a/a':np.m._$$ModuleAA,
     '/m/b/':{
               title:'模块标题',
               module:'/m/b.html'
             },
     '/m/c/':{
               title:'模块标题',
               module:np.m._$$ModuleC
             },
     '/?/m/a/':'/m/s/a.html',
     '/?/m/a/a':np.m.s._$$ModuleAA,
     '/?/m/b/':{
                 gid:'abc',
                 title:'模块标题',
                 module:'/m/b.html'
               },
     '/?/m/c/':{
                 gid:'abc',
                 title:'模块标题',
                 module:np.m._$$ModuleC
               },
 });

_$message(_options)         模块间发送消息
    to   消息目标UMI
    from 消息来源UMI
    data 消息数据
    mode 消息模式
        0 - 目标消息【默认】,只有目标节点收到消息
        1 - 目标广播,从根节点至路目标节点径上的节点收到消息
        2 - 群体广播,节点下所有子孙子孙节点收到消息

_$apply(_url) 应用私有模块

_$redirect(_url,_replaced) 重定向模块,此接口支持

_$delegate() 模块切换跳转委托,如果系统存在需退出验证模块时需使用此接口接管页面自动调整的逻辑

_$active() 激活调度器,激活之前确保注册完会被调用的模块

_$loaded(_umi,_module) 模块载入回调

更多的参数信息请参照dispatcher.js api说明

Recycle

回收和一般的event基类回收类似 ._$recycle();

Known Issues

Demo

© 1997-2013 Netease. All Rights Reserved.
comments powered by Disqus