avalon 学习笔记——代码复用(依赖注入)

来源:互联网 发布:淘宝优惠券图片头像 编辑:程序博客网 时间:2024/06/06 05:30

avalon代码复用研究

使用avalon开发已经有小半年了,从一个刚接触JavaScript的小菜成长到可以较熟悉的使用avalon处理业务逻辑,还是比较庆幸有这么好的国人写的前端框架。但是在用的过程中还是有些地方不够如意,和同事探讨关于avalon代码复用的问题,其中提到了很多方法,包括使用ms-include写成模板文件并配套封装好的VM等,还是可以解决问题的,不过这样不就违背了分离的思想了吗?之后听到同事提到angular有service的概念,所以就准备开始学学angular,简单的学习和思考后将angular的依赖注入借鉴过来,所以有了今天的博客。仅仅是拙见,欢迎指正。

废话不多说,上干货

中心思想:在笔者看来avalon.vmodels 就相当于一个avalon vm的容器我们只有获取通过id获取vm再将其设为另一个vm的属性就完成依赖注入,就是这么简单。(类似spring的ApplicationContext通过bean Id获取bean实例,其实angular的作者就是从后台转到前端,思维有点影响吧)

基础功能代码 avalon-inject.js这里写图片描述

/** * avalonContainer:avalon VM容器,提供注入VM间的依赖的功能 * 例:vm1 注入vm2(id:'service')的依赖后,vm1将拥有一个名为 "$service"的属性,持有vm2的引用 */var avalonContainer = (function () {    var doInject = function ($vm, injections) {        for (var i = 0; i < injections.length; i++) {            //注入依赖            $vm['$' + injections[i]] = avalon.vmodels[injections[i]];        }    };    /**     * 共有方法:注入依赖函数,两种调用方式     * 1:avalonContainer.inject(id, injections)     *    => id: avalon VM的$id值,此时id必须是已经通过avalon.define的VM的id     *    => injections: 数组类型,元素为被注入的avalon VM的id     * 2:avalonContainer.inject(id, injections, vmObj)     *    => id: avalon VM的$id值     *    => injections: 参见第1种     *    => vmObj: vm对象的定义,风格同avalon.define的参数     */    var inject = function () {        var $vm;        if (arguments.length == 2) {            if (($vm = avalon.vmodels[arguments[0]])) {                doInject($vm, arguments[1]);            }        } else if (arguments.length == 3) {            $vm = arguments[2];            $vm.$id = arguments[0];            doInject($vm, arguments[1]);            return avalon.define($vm);        }    };    return {        inject: inject    };})();

业务逻辑代码 avalonInjectTest.js

avalon.ready(function () {    /*    在这里可以定义通用层的私有方法    */    //将通用性的代码抽出来,定义成一个vm,对外暴露接口方法    //定义vm,一般处理和后台的数据交互,并将数据整合好交给Controller    avalon.define({        $id:'userService',        getAllUser:function (callback) {            $.getJSON('../mock/users.json', function (data) {                //在这里可以对数据进行简单处理使之能够直接交给Controller从而便于View展现                callback && callback(data);            });        }    });    //ContrllerVM    var userCtrlVM = avalonContainer.inject('userCtrl', ['userService'], {        users:[],        findUsers:function () {            //调用服务层方法,应该都是封装好了的,不需要进行过多的逻辑处理            userCtrlVM.$userService.getAllUser(function (data) {                userCtrlVM.users = data;            });        }    });    avalon.scan(document.getElementById('userCtrl'), userCtrlVM);    userCtrlVM.findUsers();});

页面做个简单展示

<!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8">    <title>avalonInject</title>    <script typet="text/javascript" src="http://libs.baidu.com/jquery/1.9.1/jquery.min.js"></script>    <script type="text/javascript" src="libs/avalon1.5.8.js"></script>    <script type="text/javascript" src="js/avalon/avalon-inject.js"></script>    <script type="text/javascript" src="js/avalon/avalonInjectTest.js"></script></head><body ms-controller="userCtrl" id="userCtrl"><div>    <ul>        <li ms-repeat="users">            <span>{{el.name}}</span>        </li>    </ul></div></body></html>

结果截屏

至此已经结束了,就是很简单代码复用,主要使用了avalon.vmodels对象。性能容错什么的都没考虑,只是自己瞎想,仅供参考,欢迎指正交流。

2 0