angular 学习理解笔记
原文: 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
-
moduleInstance.value('name', func)
- registered by value() cannot have dependencies
- func must be a constructor
-
moduleInstance.service()
- not used very often apparently
- lets you make services
- the function you provide must be a constructor (decorates
this
, no explicit return)
-
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
-
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
-
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
-
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)
-
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
- configuration phase
- all recipes are collected & configured
- providers can be configured (using modInstance.config()) here
- config() callbacks are run here
- 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
- This means that the module heirarchy is flattened out
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 25岁的心里话
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现