整个项目通过每个模块的级联形式载入整个模块。
每个模块都有一个初始化接口(initModule)用于运行该模块。
下一级模块的initModule接口在上一级的模块的initModule中调用。
var spa = (function () {
var initModule = function ( $container ) {
spa.shell.initModule( $container );
};
return { initModule: initModule };
}());
HTML容器管理
HTML管理原理
SPA项目的HTML结构与传统的HTML结构有非常不同的差异。
传统的HTML是将所有的HTML写在.html文件里。然后通过DOM方法在JS中进行操作。
SPA项目中,为了保证每个UI模块的独立性,HTML结构被以模块的形式打碎分别放置在各个UI模块总。HTML以字符串的形式存放在子模块 configMap.main_html 中。当子模块接收到父模块传递过来的容器后就通过$container.html( configMap.main_html ); 将子模块HTML结构载入到容器模块中。这样就完成了子模块HTML的加载。
这种方式看似比较零碎其实还是很容易理解的。
首先,整个项目的有一个入口容器交给root模块管理(spa.js)
<script>
$(function () { spa.initModule( $('#spa') ); });
</script>
<body>
<div id="spa"></div>
</body>
然后由root模块(spa.js) 将入口容器发送给shell( spa.shell )。
当shell模块通过接口.initModule接收到shell容器后。
spa.shell.initModule( $container );
在spa.shell.js中有shell负责管理的每个子模块的容器模板。存放在
configMap = {
main_html : String()
+ '<div class="spa-shell-head">'
+ '<div class="spa-shell-head-logo"></div>'
+ '<div class="spa-shell-head-acct"></div>'
+ '<div class="spa-shell-head-search"></div>'
+ '</div>'
+ '<div class="spa-shell-main">'
+ '<div class="spa-shell-main-nav"></div>'
+ '<div class="spa-shell-main-content"></div>'
+ '</div>'
+ '<div class="spa-shell-foot"></div>'
+ '<div class="spa-shell-modal"></div>'
}
现将会把configMap.main_html中的容器模板载入到这个容器中
stateMap.$container = $container;
$container.html( configMap.main_html );
这样就完成了子模块中HTML的加载。当然shell中的HTML结构只是提供shell下子模块的容器。
也就是说这里的shell其中一个职责就是管理整个项目的容器。然后将这些容器通过子模块初始化接口中的参数传递给子模块。然后子模块在通过$container.html( configMap.main_html );将子模块的结构加载到DOM中。 这样就完成了整个项目的HTML结构的加载。
子模块加载不同的情况
上一级模块通过参数的形式将下级模块所需要DOM容器的传递到下一个模块中,也就是说上一级模块管理着下一级模块的容器。
如果 子模块容器 与 上级模块容器 是平行关系:
子模块是一个独立的容器。也可以理解为子模块的容器与传递过来的容器是并行的兄弟关系。那么就把整个上级容器直接传递到这个子模块中。然后通过append方法在上级容器后面追加一个容器。
如果 子模块容器 是 上级容器中的子容器
那么就直接将子模块容器传递过去即可。
jquery管理机制UI模块都设计到对DOM的操作,平凡的进行$('#ABC')类似操作极大的影响了浏览器的性能。所以在UI模块中有一个统一管理jqueryDOM的地方。
首先在initModule接口中。
initModule = function ( $append_target ) {
$append_target.append( configMap.main_html ); // 这里将模块中的HTML结构载入进容器
stateMap.$append_target = $append_target; .// 这里将容器先丢到模块状态管理机制中。 以便以后使用
setJqueryMap(); // 这里调用模块JDOM的缓存机制
}
setJqueryMap = function () {
var
$append_target = stateMap.$append_target,
$slider = $append_target.find( '.spa-chat' );
// 这里将容器缓存起来,并且把以后需要用到的DOM节点统一进行获取和缓存。之后使用DOM节点就直接通过jqueryMap。
jqueryMap = {
$slider : $slider,
$head : $slider.find( '.spa-chat-head' ),
$toggle : $slider.find( '.spa-chat-head-toggle' ),
$title : $slider.find( '.spa-chat-head-title' ),
$sizer : $slider.find( '.spa-chat-sizer' ),
$msgs : $slider.find( '.spa-chat-msgs' ),
$box : $slider.find( '.spa-chat-box' ),
$input : $slider.find( '.spa-chat-input input[type=text]')
};
};
大体的思路就是从initModule参数中获取容器并把模块HTML结构加载到这个容器中,然后由setJqueryMap获取HTML结构中的DOM,并缓存到jqueryMap中。
最后最后再总结一下 模块的调用机制 HTML容器分发给各个子模块。 上级模块管理着HTML容器(shell)。子模块管理着子模块自身的HTML结构。 通过$container.html( configMap.main_html );将HTML结构载入到HTML容器中,形成了一次关联并且让模块HTML结构载入到页面中。在通过setJqueryMap获取子模块DOM节点便于模块中内部的DOM操作或将DOM传递到下一级的子模块中。
结合 模块的调用机制 HTML容器管理 jquery管理机制 就将源码只是干巴巴的HTML字符串转换成了有组织的活生生的DOM结构。 并且在每个模块中都有了操作自身模块DOM结构的jqueryMap。
PS
我要告诉大家这本书真的很难懂,并且这些东西还是才是刚开始。这些只是整个项目HTML结构的机制。后面还有每个模块的状态管理机制。 模块间的事件分发管理机制。整个项目统一的状态管理机制用于协调整个项目间每个模块的状态。然后就是数据模型。 还有后端的node express socket.io mongodb。 感觉整个项目都是围绕着socket.io 接口的方式开发的。
最后我想说,学前端的同志们。 如果你想在复杂的项目中脱离混乱的苦海。那么就花点时间看看这本书吧。这本书不经长知识重要的是长见识!!!