详解angularjs的数组传参方式的简单实现


Posted in Javascript onJuly 28, 2017

初学 angularjs时,对 数组传参方式感到很好奇([‘a', ‘b', function(a,b){}]),它到底怎么实现的呢?后来由于工作很忙,对这个问题也就慢慢忘记了。

今天闲来无事,有想到了这个问题。最简单的方法就是查看他的源代码。无奈本人E文不好,不说看他的设计逻辑,仅看英文注释就够我头疼了。尝试闭门造车,最终竟然把车造出来了。

既然自己造的车,就要带上自己的名(取姓名拼音第一个字母),就叫他mqyJs把,下面是演示的调用方法:

var app2 = mqyJs.applicationCreate([{ name: '直接传入SCOPE' }, '$hello', '$world', function($scope, $hello, $world) {
  return $scope.name + ": " + $hello.name + $world.name;
}]);

核心部分如下:

//框架开设
var mqyJs = {
  //服务注册
  servicesList: {},
  servicesRegister: function(name, value) {
    this.servicesList[name] = value;
  },
  //应用创建
  applicationList: [],
  applicationCreate: function(_opts, _args) {
    if (!_args) {
      _args = _opts;
      _opts = {}
    }
    _opts.scope = _opts.scope || {
      name: 'SCOPE没有设置'
    };
    if (!(_args instanceof Array)) {
      _args = ['$scope', _args];
    }
    if (typeof _args[_args.length - 1] != 'function') {
      throw new Error('参数中没有指定运行函数');
    }
    _args.map((arg, index) => {
      if (typeof arg == 'string') {
        if (arg === '$scope') {
          _args[index] = _opts.scope;
        } else {
          if (!!arg && !(arg in this.servicesList)) {
            throw new Error('插件:' + arg + ' 还没有注册');
          }
          _args[index] = this.servicesList[arg];
        }
      }
    });
    return this.applicationList[this.applicationList.push({
      run: function(callback) {
        if (typeof callback != 'function') {
          callback = function(_opts) { return _opts; }
        }
        return callback(_args[_args.length - 1].apply(null, _args));
      }
    }) - 1];
  }
};
//框架结束

通过 servicesRegister,可以注册 服务,比如 angularjs 的 $http;

//插件开始
mqyJs.servicesRegister('$hello', {
  name: '你好'
});
mqyJs.servicesRegister('$world', {
  name: '世界'
});
mqyJs.servicesRegister('$china', {
  name: '中国'
});
//插件结束

最终,对所有注册的应用,自动执行

/**
 * 初始化完成后系统自动运行
 * 比如网页中 放到 window.onload
 */
mqyJs.applicationList.map(function(app, index) {
  console.log('自动调用 -> APP #' + index + ' -> ' + app.run());
});

尝试跑一下代码,能自动识别参数类型,完美执行。

不传入 $scope 时,程序会自动创建一个 $scope。

//演示代码 开始
var app = mqyJs.applicationCreate(['$scope', '$hello', '$china', function($scope, $hello, $china) {
  return $scope.name + ": " + $hello.name + $china.name;
}]);


var app2 = mqyJs.applicationCreate([{ name: '直接传入SCOPE' }, '$hello', '$world', function($scope, $hello, $world) {
  return $scope.name + ": " + $hello.name + $world.name;
}]);

 

var app3 = mqyJs.applicationCreate([{ name: 'world也直接传入' }, '$hello', { name: '地球' }, function($scope, $hello, $world) {
  return $scope.name + ": " + $hello.name + $world.name;
}]);


var app4 = mqyJs.applicationCreate(function($scope) {
  return $scope.name;
});

var opts = {
  scope: {
    name: '自定义SCOPE'
  }
};
var app5 = mqyJs.applicationCreate(opts, function($scope) {
  return $scope.name;
});

app4.run(function(result) {
  console.log('手动调用 -> RESULT -> ' + result);
});

//演示代码 结束

为了方便测试,再把代码重新写一遍,直接复制下面的代码到 浏览器控制台即可测试

//框架开设
var mqyJs = {
  //服务注册
  servicesList: {},
  servicesRegister: function(name, value) {
    this.servicesList[name] = value;
  },
  //应用创建
  applicationList: [],
  applicationCreate: function(_opts, _args) {
    if (!_args) {
      _args = _opts;
      _opts = {}
    }
    _opts.scope = _opts.scope || {
      name: 'SCOPE没有设置'
    };
    if (!(_args instanceof Array)) {
      _args = ['$scope', _args];
    }
    if (typeof _args[_args.length - 1] != 'function') {
      throw new Error('参数中没有指定运行函数');
    }
    _args.map((arg, index) => {
      if (typeof arg == 'string') {
        if (arg === '$scope') {
          _args[index] = _opts.scope;
        } else {
          if (!!arg && !(arg in this.servicesList)) {
            throw new Error('插件:' + arg + ' 还没有注册');
          }
          _args[index] = this.servicesList[arg];
        }
      }
    });
    return this.applicationList[this.applicationList.push({
      run: function(callback) {
        if (typeof callback != 'function') {
          callback = function(_opts) { return _opts; }
        }
        return callback(_args[_args.length - 1].apply(null, _args));
      }
    }) - 1];
  }
};
//框架结束
//插件开始
mqyJs.servicesRegister('$hello', {
  name: '你好'
});
mqyJs.servicesRegister('$world', {
  name: '世界'
});
mqyJs.servicesRegister('$china', {
  name: '中国'
});
 
var app = mqyJs.applicationCreate(['$scope', '$hello', '$china', function($scope, $hello, $china) {
  return $scope.name + ": " + $hello.name + $china.name;
}]);


var app2 = mqyJs.applicationCreate([{ name: '直接传入SCOPE' }, '$hello', '$world', function($scope, $hello, $world) {
  return $scope.name + ": " + $hello.name + $world.name;
}]);


var app3 = mqyJs.applicationCreate([{ name: 'world也直接传入' }, '$hello', { name: '地球' }, function($scope, $hello, $world) {
  return $scope.name + ": " + $hello.name + $world.name;
}]);


var app4 = mqyJs.applicationCreate(function($scope) {
  return $scope.name;
});

var opts = {
  scope: {
    name: '自定义SCOPE'
  }
};
var app5 = mqyJs.applicationCreate(opts, function($scope) {
  return $scope.name;
});

app4.run(function(result) {
  console.log('手动调用 -> RESULT -> ' + result);
});
 
//插件结束
mqyJs.applicationList.map(function(app, index) {
  console.log('自动调用 -> APP #' + index + ' -> ' + app.run());
});

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
关于实现代码语法标亮 dp.SyntaxHighlighter
Feb 02 Javascript
firefox浏览器下javascript 拖动层效果与原理分析代码
Dec 04 Javascript
JavaScript CSS菜单功能 改进版
Dec 20 Javascript
javascript 事件处理程序介绍
Jun 27 Javascript
基于javascript、ajax、memcache和PHP实现的简易在线聊天室
Feb 03 Javascript
jquery获取多个checkbox的值异步提交给php
Jul 07 Javascript
Angular指令封装jQuery日期时间插件datetimepicker实现双向绑定示例
Jan 22 Javascript
Javascript中类式继承和原型式继承的实现方法和区别之处
Apr 25 Javascript
vuejs实现递归树型菜单组件
Jan 13 Javascript
利用hasOwnProperty给数组去重的面试题分享
Nov 05 Javascript
vue 手机物理监听键+退出提示代码
Sep 09 Javascript
jquery实现简单每周轮换的日历
Sep 10 jQuery
js 获取html5的data属性实现方法
Jul 28 #Javascript
jQuery获取table表中的td标签(实例讲解)
Jul 28 #jQuery
浅谈JS中的常用选择器及属性、方法的调用
Jul 28 #Javascript
js原生代码实现轮播图的实例讲解
Jul 28 #Javascript
js弹性势能动画之抛物线运动实例详解
Jul 27 #Javascript
js学习总结之dom2级事件基础知识详解
Jul 27 #Javascript
Angular指令之restict匹配模式的详解
Jul 27 #Javascript
You might like
php中数据的批量导入(csv文件)
2006/10/09 PHP
奇怪的PHP引用效率问题分析
2012/03/23 PHP
深入mysql_fetch_row()与mysql_fetch_array()的区别详解
2013/06/05 PHP
Yii2中datetime类的使用
2016/12/17 PHP
js下将字符串当函数执行的方法
2011/07/13 Javascript
最佳的addEvent事件绑定是怎样诞生的
2011/10/24 Javascript
javascript对下拉列表框(select)的操作实例讲解
2013/11/29 Javascript
js判断60秒以及倒计时示例代码
2014/01/24 Javascript
JavaScript中使用ActiveXObject操作本地文件夹的方法
2014/03/28 Javascript
JavaScript检查某个function是否是原生代码的方法
2014/08/20 Javascript
JQuery节点元素属性操作方法
2015/06/11 Javascript
标准的js无缝滚动效果
2016/08/30 Javascript
JS控制FileUpload的上传文件类型实例代码
2016/10/07 Javascript
jQuery实现拖拽可编辑模块功能代码
2017/01/12 Javascript
简单实现js轮播图效果
2017/07/14 Javascript
JS返回顶部实例代码
2020/08/09 Javascript
vue中使用element-ui进行表单验证的实例代码
2018/06/22 Javascript
ES6 Symbol数据类型的应用实例分析
2019/06/26 Javascript
vue移动端下拉刷新和上滑加载
2020/10/27 Javascript
vue-router定义元信息meta操作
2020/12/07 Vue.js
python实现的守护进程(Daemon)用法实例
2015/06/02 Python
在Django框架中编写Context处理器的方法
2015/07/20 Python
Python 基于Twisted框架的文件夹网络传输源码
2016/08/28 Python
windows7 32、64位下python爬虫框架scrapy环境的搭建方法
2018/11/29 Python
django celery redis使用具体实践
2019/04/08 Python
flask框架渲染Jinja模板与传入模板变量操作详解
2020/01/25 Python
python实现门限回归方式
2020/02/29 Python
python selenium xpath定位操作
2020/09/01 Python
CSS3 Pie工具推荐--让IE6-8支持一些优秀的CSS3特性
2014/09/02 HTML / CSS
HTML5 图片悬停放大的实现代码示例
2019/12/04 HTML / CSS
美国CVS药店官网:CVS Pharmacy
2018/07/26 全球购物
暑期实践个人总结
2015/03/06 职场文书
陪护人员误工证明
2015/06/24 职场文书
Python数据可视化之用Matplotlib绘制常用图形
2021/06/03 Python
Go 通过结构struct实现接口interface的问题
2021/10/05 Golang
如何使用注解方式实现 Redis 分布式锁
2022/07/23 Redis