当前位置: 首页 > news >正文

学习 AngularJS (三) module

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

再看 kityminder-editor 部分代码, 上来就是 angular module:

angular.module('kityminderEditor', [
    'ui.bootstrap',
    'ui.codemirror',
    'ui.colorpicker'
])
       .config(...) ...

看不明白, 怎么办? 只能接着学习了!

查 angularjs 英文官网, 终于找到 module 的网页了:
    https://docs.angularjs.org/guide/module

 

所以, 什么是一个 Module?

原文: You can think of a module as a container for the different parts of your app - controllers,
  services, filters, directives, etc.

这样从用途上定义了模块(module)是一个我的应用的(杂七杂八的)各种东西的总容器.
于是, 自然而然的问题产生了, 一个 app 对应一个还是多个 module? 一个 module 的生命周期如何?

Why?

大部分应用有一个 main 方法来实例化对象, 并将应用的各个不同部分 wires(关联起来)在一起.
Angular 的应用没有这个 main 方法. 而是用 modules 来声明应用是如何启动(bootstrap)的.

* 声明式语法容易理解.
* 代码打包为可重用的 module.
* module 可按照任意顺序加载, 甚至并行加载, 因为模块延迟执行
* 单元测试只需要加载所需模块而非所有, 从而快一些
* end-to-end 测试可使用 module 重载配置.

看一下 module 的接口, 似乎是一组注册/定义各种类部件的函数集合: 
   https://docs.angularjs.org/api/ng/type/angular.Module

class angular.Module {
  provider(name, providerType) -- 注册 provider?
  factory(name, providerFunction) -- 注册 factory?
  service(name, ctor) -- 注册 service
  value(name, object) -- 变量 name=object ?
  constant(name, object) -- 常量 name=object ...?
  decorator(The, This) ...修饰器 ?
  animation(name, animationFactory)
  filter(name, filterFactory) -- 注册过滤器
  controller(name, ctor) -- 注册控制器
  directive(name, directiveFactory) -- 应是注册指令
  config(configFn) -- 注册当模块加载时执行的代码块, 一般对 service 配置有用.
  run(initialitionFn) -- 注册当 injector 结束加载了所有模块时运行的代码块...

  string[] requires: 依赖的其它模块列表, injector 会加载它们在此模块之前.
  string name -- 模块名
}

这里 requires[] 显然用于解决依赖注入问题.

引用这个 myApp 模块: 如使用 <div ng-app='myApp'>. 这将启动这个 app 使用定义的模块.

(这样的话, 一个 app 大概就是一个 module, 估计还可以有多个其它 module).

 

Recommended Setup

推荐将 app 分解为多个 module, 如这样:
* 一个 module 为一个特性
* 一个 module 为可重用的组件 (尤其是 directives, filters)
* 一个应用级 (application level) module 依赖上面的 modules, 并包含初始化代码.

(这样, angluar module 的概念大致 对应一个js文件, 里面含模块功能代码, 及所依赖的其它模块.
  与 NodeJS 中的使用 define(module_name, dependence, factory() {...}) 定义的模块应是类似概念)

 

Module Loading & Dependencies

最简单形式包含两种可执行的代码块:
* 配置 -- 在 provider 注册和配置阶段执行. 此时只有 providers 和 constant 可被注入.
* 执行 -- 注入器(iinjector)创建之后执行, 用于启动 app. 只有 instances 和 contants 可被注入.

angular.module('myModule', [])  // 声明一个名为 myModule 的模块, 依赖列表为 emtpy
  .config(function(injectables-providers) {
    // 配置块, 可以有任意个. 只能注入 providers (非 instances)
  })
  .run(function(injectables-instances) {
    // 运行块, 可以有任意个. 只能注入 instances (非 providers)
  });


(可能这里分两阶段才能正确完成 module 的初始化, 以防止模块相互依赖, 初始化不完全的情况)

 

Configuration Blocks

module.value() 方法等价于 $provide.value();
   .drective() 等价于 $compileProvider.directive() 等等.
这些在 module.config() 中以各种 $provide 方式提供.

现学现查, 从 kityminder-editor 中任意找了一个 ui/directive/arrange/arrange.directive.js:

angular.module('kityminderEditor') // 如果模块已经存在, 估计会取出该模块.
  .directive('arrange', [... {  // 定义指令 arrange, 依赖部分略.
    return { 此指令的实现对象 };
  }]);

再看其它 directive 形式也类似, 另再看一个 filter lang.filter.js:

angular.module('kityminderEditor')
  .filter('lang', [... function(config, lang) {
    return 工厂方法;
  }]);

估计是定义 lang 过滤器, 返回一个工厂方法, 细节先略去.

(还是买本 angularjs 的最新技术图书看看吧...)

 

Run Blocks

用于启动应用, 如 angular.module('myModule').run( function () {...} );

(在 kityminder 中暂时没找到这种块... 只有 config 块. 可能是用 ng-app 的方式启动应用的.)

 

Creation vs. Retrieval

(每次我瞎猜之后, 都能看到一些推翻我猜测的文档...)

* 使用 angular.module('myModule', []) 将创建名为 myModule 的模块, 覆盖原有的.
* 使用 angular.module('myModule') 获取已存在的 module. (? 如果不存在呢)

于是下面两个对比就终于弄明白了(其实原来也没注意到有什么区别...) :

// 被最先引入的 kityminder.app.js, 创建了模块.
angular.module('kityminderEditor', [dependencies ... 略])
  .config(...);


// 后面引入的, 例如 commandBinder.service.js, 向模块中添加 service,filter,directive 等.
angular.module('kityminderEditor')  // 注意这里没有 [...] 参数
  .service(...);

引入当然是用 script 标记:

<!-- 前面大量各种库 js 引入 -->

<script src="ui/kityminder.app.js"></script>
<script src="ui/service/commandBinder.service.js"></script>
<!-- dev 模式下的 kityminder index.htm 后面还有大量的 js 引入 -->

由于使用了这么多 js 库, 我都有点担心机器内存不够...

 

转载于:https://my.oschina.net/u/232554/blog/540541

相关文章:

  • Json序列化之.NET开源类库Newtonsoft.Json
  • C/C++ 库函数 是否调用 WinAPI
  • 构造汽车
  • 违反约束或者主外键删除数据
  • 不平衡学习方法理论和实战总结
  • Windows Cygwin Redis 安装(转)
  • apche commons项目简介
  • CAS (2) —— Mac下配置CAS到Tomcat(客户端)
  • Median of Two Sorted Arrays
  • 固态硬盘上安装Windows8(ghost)启动问题
  • 王家林每日大数据语录Spark篇0003
  • [hive小技巧]同一份数据多种处理
  • 【191】◀▶ Powershell 命令集 Cmdlets
  • Github访问慢解决办法
  • ActionContext 中的数据详解
  • 03Go 类型总结
  • Django 博客开发教程 16 - 统计文章阅读量
  • ECMAScript 6 学习之路 ( 四 ) String 字符串扩展
  • js继承的实现方法
  • Linux学习笔记6-使用fdisk进行磁盘管理
  • Nginx 通过 Lua + Redis 实现动态封禁 IP
  • opencv python Meanshift 和 Camshift
  • seaborn 安装成功 + ImportError: DLL load failed: 找不到指定的模块 问题解决
  • Solarized Scheme
  • Spring Cloud(3) - 服务治理: Spring Cloud Eureka
  • Storybook 5.0正式发布:有史以来变化最大的版本\n
  • vue 个人积累(使用工具,组件)
  • 分布式任务队列Celery
  • 精益 React 学习指南 (Lean React)- 1.5 React 与 DOM
  • 实战:基于Spring Boot快速开发RESTful风格API接口
  • ​如何在iOS手机上查看应用日志
  • # C++之functional库用法整理
  • %@ page import=%的用法
  • (2)(2.4) TerraRanger Tower/Tower EVO(360度)
  • (C#)Windows Shell 外壳编程系列9 - QueryInfo 扩展提示
  • (二十五)admin-boot项目之集成消息队列Rabbitmq
  • (机器学习的矩阵)(向量、矩阵与多元线性回归)
  • (算法)前K大的和
  • (一)Mocha源码阅读: 项目结构及命令行启动
  • (转)机器学习的数学基础(1)--Dirichlet分布
  • (转载)虚幻引擎3--【UnrealScript教程】章节一:20.location和rotation
  • ***php进行支付宝开发中return_url和notify_url的区别分析
  • .NET : 在VS2008中计算代码度量值
  • .Net mvc总结
  • .Net 应用中使用dot trace进行性能诊断
  • .NET/C# 项目如何优雅地设置条件编译符号?
  • .Net高阶异常处理第二篇~~ dump进阶之MiniDumpWriter
  • .NET精简框架的“无法找到资源程序集”异常释疑
  • @private @protected @public
  • @RequestParam @RequestBody @PathVariable 等参数绑定注解详解
  • @value 静态变量_Python彻底搞懂:变量、对象、赋值、引用、拷贝
  • [20150904]exp slow.txt
  • [android] 天气app布局练习
  • [android]-如何在向服务器发送request时附加已保存的cookie数据
  • [Angular] 笔记 21:@ViewChild