原文:https://github.com/eoinkelly/notes/blob/master/angular/book-building-web-apps-w-angular/angular.md

---------------------------------------------------------------------------------

Modules

You can create and retrieve modules with the angular.module() function

var modInstance = angular.module('someName', []); // create 'someName' module
var myNameMod = angular.module('someName'); // retrieve a reference to an existing model
  • A module acts as a container for other managed objects
  • The ng-app directive is given the name of a module.
  • Modules can contain any kind of object, not just angular specific ones

In angular you can declarativly express dependencies between modules

  • Pros

    • you can swap collaborators as you need them
    • you are not responsible for creating or destroying (managing life cycle) of collaborators - angular does it for you - this means less code but also less control I guess
      • if you object doesn't create or destroy any of its collaborators, it has less jobs
      • it makes all the collaborators swappable (hence easier to change)
    • it lets you unit test much easier. The ability to swap collaborators is very important for testability

To take advantage of angular DI system, you need to tell it about your code by registering your code in modules.

Angular modules do not store instances of the objects your code needs - they store factories/recipes/constructors that can create these instances

  • The $provide service allows us to register our recipes
  • The recipes are then interpreted by the $injector service (which creates and wires up their dependencies too)
  • objects created from a recipe are called services

NB Angular will only interpret a given recipe once during the applications life cycle - there will only every be one instance of each service object!!!

Consequences

  • there is only one of each controller, filter, directive, service that you register
  • if I want to use Angular DI/modules for my own code, I need to remember that the constructor function I provide will only be run one time during the lifetime of the app.
  • Angular services are singletons!!!
  • ? does this imply that services are not useful for models?

7 ways of registering an object with Angular DI system

  1. moduleInstance.value('name', func)

    • registered by value() cannot have dependencies
    • func must be a constructor
  2. moduleInstance.service()

    • not used very often apparently
    • lets you make services
    • the function you provide must be a constructor (decorates this, no explicit return)
  3. moduleInstance.factory('name', )

    • allows to register any arbitrary object-creating code i.e. the function does not have to be a constructor - it can return anything
    • the function you pass can be used as the module pattern (it can have "private" variables, and return it's public interface)
    • factory is the most common way of registing code with the DI system
  4. moduleInstance.constant('name', value)

    • lets you register a constant that can be declared as a dependency by other modules
    • You could put constants within the function you pass to factory but this is better because
      • they can be swapped out for tests
      • you can re-use the service across many applications
      • con: they don't have default values - the client app has to specify every constant
  5. moduleInstance.provider('name', function)

    • all of the other registration methods are sugar for this one
    • it must return an object that contains a $get property which is a factory function
    • a provider is an object that embeds factory function in it's $get property
    • it can also expose other functions as properties and have hidden data so you can have a default configuration that gets overridden by the functions it exposes.
      • it is the most verbose but most flexibly way of registering
  6. moduleInstance.config(func(fooProvider))

    • note there is no name parameter, only a function
    • allows you to call functions on the provider object before it's $get property is invoked to create the service
    • these functions get run during the config phase (they can change the recipe)
    • gets passed in an instance of a provider (decided by the parameter name)
    • Two ways of registering config functions for angular modules:
    angular.module('my-foo-mod', [], function (myServiceProvider) {
    // I am **the** config function because I am the third argument (implicit - less obvious)
    // I am the only one - this is less flexible
    // the parameter passed in here is a reference to the **provider** that creates the service instances
    // angular uses its argument parsing magic to know find the provider for 'myService'
    myServiceProvider.setMaxLen(5);
    }); // This form is prefered as it is more explicit and flexible
    angular.module('my-foo-mod', [])
    .config(function () {
    // I am a config function
    })
    .config(function () {
    // so am I
    })
    • within the config() function we are calling things in the public interface of the provider object (which contains the factory object in $get). This is like changing the recipe, not creating the service using the original recipe and then tweaking it
    • Angular uses it's magic "parse the function text" trick to find the right provider using the naming convention fooProvider (the provider for foo)
  7. moduleInstance.run(func(...))

    • note there is no name parameter, only a function
    • code that should be invoked at the run phase of the module

Function objects registered as modules get an $inject attribute which points to an array of strings representing their dependencies - this is what all the sugar ways of declaring dependencies does.

Inspecting Angular from the console

How do I inspect the angular objects in console?

angular.element($0).scope(); // or just type  $scope with batarang installed

If you change value of some model on $scope and want to have this change reflected in the running application, you need to call $scope.$apply() after making the change.

example here

??? You can almost do it for services:

$('body').injector().get('myMod'); // works iff you Angular is using full jQuery

Module lifecycle

Angular module has two phases

  1. configuration phase

    • all recipes are collected & configured
    • providers can be configured (using modInstance.config()) here
    • config() callbacks are run here
  2. run phase
    • any post-instantiation logic is run here
    • the equivalent of a main method in other languages
    • a module can have multiple run blocks
    • run() callbacks are run here
    • you can use run callbacks to add variables to the $rootScope

Angular modules can be combined into other modules

  • groups of related services can be combined into re-usable modules
  • the top level (application) module can just declare its dependencies on what it needs

Angular has both a services namespace and a module heirarchy. All services are global singletons so the modules (a heirarchy of service creation recipes) eventually creates a flat services namespace.

  • services can declare dependencies on other services, values, constants (they don't care what modules these are in however)
  • modules (each of which can contain multiple services) can declare dependencies on each other

Service visiblity

  • All services are combined into a global namespace so they can all depend on each other no matter what module they are defined in.

    • This means that the module heirarchy is flattened out

      • The module herirarchy is still worthwhile because it helps for organisating code and testing
    • You can override services by defining ones with the same name that are "closer" to the service that needs them.
    • Services defined in modules that are closer to the root of the module heirarchy will override those in child modules
    • There is currently no way of having a service that is private to a module
    • There is currently no way of restricting the visibility of a service

angular 学习理解笔记的更多相关文章

  1. batch normalization学习理解笔记

    batch normalization学习理解笔记 最近在Andrew Ng课程中学到了Batch Normalization相关内容,通过查阅资料和原始paper,基本上弄懂了一些算法的细节部分,现 ...

  2. ASCII, Unicode, UTF-8, 8进制, 16进制等各种编码学习理解笔记

    字符编码的发展历史 Unicode和UTF-8有何区别? 在这个问题下的于洋的最高票回答中,比较完整地介绍了字符编码的发展历史,为了便于记忆,再次简要概括一番. 一个字节:最初一个字节的标准是混乱的, ...

  3. angular学习笔记(三十一)-$location(2)

    之前已经介绍了$location服务的基本用法:angular学习笔记(三十一)-$location(1). 这篇是上一篇的进阶,介绍$location的配置,兼容各版本浏览器,等. *注意,这里介绍 ...

  4. angular学习笔记(三十)-指令(7)-compile和link(2)

    继续上一篇:angular学习笔记(三十)-指令(7)-compile和link(1) 上一篇讲了compile函数的基本概念,接下来详细讲解compile和link的执行顺序. 看一段三个指令嵌套的 ...

  5. angular学习笔记(三十)-指令(6)-transclude()方法(又称linker()方法)-模拟ng-repeat指令

    在angular学习笔记(三十)-指令(4)-transclude文章的末尾提到了,如果在指令中需要反复使用被嵌套的那一坨,需要使用transclude()方法. 在angular学习笔记(三十)-指 ...

  6. angular学习笔记(三十一)-$location(1)

    本篇介绍angular中的$location服务的基本用法,下一篇介绍它的复杂的用法. $location服务的主要作用是用于获取当前url以及改变当前的url,并且存入历史记录. 一. 获取url的 ...

  7. angular学习笔记(三十)-指令(10)-require和controller

    本篇介绍指令的最后两个属性,require和controller 当一个指令需要和父元素指令进行通信的时候,它们就会用到这两个属性,什么意思还是要看栗子: html: <outer‐direct ...

  8. angular学习笔记(三十)-指令(7)-compile和link(1)

    这篇主要讲解指令中的compile,以及它和link的微妙的关系. link函数在之前已经讲过了,而compile函数,它和link函数是不能共存的,如果定义了compile属性又定义link属性,那 ...

  9. angular学习笔记(三十)-指令(5)-link

    这篇主要介绍angular指令中的link属性: link:function(scope,iEle,iAttrs,ctrl,linker){ .... } link属性值为一个函数,这个函数有五个参数 ...

随机推荐

  1. linux内核同步之每CPU变量、原子操作、内存屏障、自旋锁【转】

    转自:http://blog.csdn.net/goodluckwhh/article/details/9005585 版权声明:本文为博主原创文章,未经博主允许不得转载.   目录(?)[-] 一每 ...

  2. For循环中不可以嵌套RDD操作

    今天犯了一个致命理解错误,Spark中的RDD Map操作只是一个计算式的传递,并不是Action,也就是在for循环中不会产生真正的计算. 因此,如果for循环中出现了RDD的Map类似操作,都会引 ...

  3. 1.kafka的介绍

    kafka是一种高可用,高吞吐量,基于zookeeper协调的分布式发布订阅消息系统. 消息中间件:生产者和消费者 举个例子: 生产者:做馒头,消费者:吃馒头,数据流:馒头 如果消费者宕机了,吃不下去 ...

  4. Mysql中大表添加索引的办法

    Hash索引与 Btree索引的区别http://database.51cto.com/art/201010/229525.htm Creating Indexes/Sorting on very l ...

  5. 本地配置环境打开项目出现404/本地wampserver配置伪静态以及php.ini配置

    本地wamp/phpstudy实现虚拟主机后,出现了500错误看日志看到.htaccess: Invalid command ‘RewriteEngine’, perhaps misspelled o ...

  6. Redis 源码走读(二)对象系统

    Redis设计了多种数据结构,并以此为基础构建了多种对象,每种对象(除了新出的 stream 以外)都有超过一种的实现. redisObject 这个结构体反应了 Redis 对象的内存布局 type ...

  7. HDU 6342.Problem K. Expression in Memories-模拟-巴科斯范式填充 (2018 Multi-University Training Contest 4 1011)

    6342.Problem K. Expression in Memories 这个题就是把?变成其他的使得多项式成立并且没有前导零 官方题解: 没意思,好想咸鱼,直接贴一篇别人的博客,写的很好,比我的 ...

  8. 简单DP【p2758】编辑距离

    Description 设A和B是两个字符串.我们要用最少的字符操作次数,将字符串A转换为字符串B.这里所说的字符操作共有三种: 1.删除一个字符: 2.插入一个字符: 3.将一个字符改为另一个字符: ...

  9. java常见异常归纳

    1.java.lang.NullPointerException(空指针异常)    调用了未经初始化的对象或者是不存在的对象 经常出现在创建图片.调用数组这些操作中,比如图片未经初始化,或者图片创建 ...

  10. Spring MVC的工作机制

    1. Spring MVC请所有的请求都提交给DispatcherServlet,它会委托应用系统的其他模块负责负责对请求进行真正的处理工作. 2. DispatcherServlet查询一个或多个H ...