AngularJS 学习笔记-基础导读
基础学习: http://www.runoob.com/angularjs/angularjs-tutorial.html
AngularJS 构建单页面应用或者复杂的回合制web应用,本文只是对AngularJS的整体概念进行梳理,并非具体样例演示,具体的样例可以到上述基础教程中直接运行。
1.MVC和MVVM
Application的MVC:
-- Controller: 基于用户的选择,控制选择不同的业务模型数据,选择不同的视图显示数据--
-- Model: 业务数据
-- View:用于显示视图数据的页面
-- Sevice是对业务数据的操作,实现具体的业务逻辑,它关注的是多个MVC线路的横切面,service可以互相调用以实现复杂的业务逻辑
-- 每一次数据的展示都是一次新的请求,实现整个页面的刷新
MVVM:
-- Mode: 业务数据
-- VM:视图数据模型,用于实现业务数据与视图的双向绑定
-- View:展现数据的视图
AnguarJS是基于MVVM,是对前端视图展示的一个框架,可以理解为只是针对于整个MVC工程的View部分
-- Mode:一般通过AJAX获取获取restful 获取后台JSON数据并转换为JS对象
-- Service:通过AngularJS的创建的service并依赖注入,通用的service也只是关注横切面,多个service直接可以相互调用实现复杂的业务逻辑
-- Controller: Controller,与一个$scope相对应,页面上通过ng-controller来确定这个scope作用域的范围
-- VM:是controller的$cope作用域,实现了数据与页面视图(指令)的相互绑定,通过$scope修改数据,指令显示的数据也同时被修改为同样数据。
-- View: ng-app,ng-controller,通过这俩内置指令关联上js代码中的module和controller,并且确定了该controller的作用域, 内置和自定义指令,ng-view和HTML是具体的用于视图的显示,这些被包含在哪个ng-controller下就会实现在其对应的scope作用域下的双向绑定。
-- 自定义指令和路由的指令的调用作为视图的一部分,指令的实现需要在js中定义,内置指令是已经有angularjs框架实现了
2.初始化流程:
1、浏览器载入HTML,然后把它解析成DOM。
2、浏览器载入angular.js脚本。
3、AngularJS等到DOMContentLoaded事件触发。
4、AngularJS寻找解析ng-app指令及ng-controller指令,这个指令指示了应用的边界。
5、解析anguarJS代码
6、使用ng-app中指定的模块来配置注入器($injector)。
7、注入器($injector)是用来创建“编译服务($compile service)”和“根作用域($rootScope)”的。
8、编译服务($compile service)是用来编译DOM并把它链接到根作用域($rootScope)的。
9、配置$provide生成或者直接用app api生成的 provide,factory,service
10、在载人模块代码时,根据依赖关系,顺序执行模块的config方法,先执行最顶层依赖模块的config方法
111、在载入完毕所有模块代码,根据依赖关系,顺序执行模块的run方法,先执行最顶层依赖模块的run方法
3.AngualrJS组件结构:
Module -> Controller ->$scope -> view
-> Controller ->$scope -> view
-> Directive
-> Service(factory,service,provider)
-> Route
-> Filter
Module ->.......................
Module可以用于组织多模块实现代码的服务,或者用来代码结构分包
controller及作用域是Mode和VIew的枢纽,Controller会对应于某一View(ng-Controller确定的范围),在VIew上的修改数据的行为,会进入controller的实例的$scope的方法,一个controller会跟一个$scope一一对应
Route&Directive&Filter可重用于当前module不同的controller,在不同的视图下就会对应于不同的controller及作用域下
Route:在模块下预定义当前模块所需的route对象,ng-view会根据浏览器url的变化显示不同的route对象
-- 如果所有的route对象共享于一个controller,controller可以通过$route对象获取当前route对象就对route对象变化的事件做出处理
-- 每个route对象可以指向指定的controller,只有当切换到这个route对象,才会去创建生成这个controller的实例,这就是懒加载
-- ng-view 决定了当前route对象所在的View,就决定了对应的controller
4.Module模块
定义方法
config函数
run函数
5. 依赖注入 --
Module("app", []).service("serviceName", function(){
reutrn {...}
});
Module("app", []).factory("serviceName", function(){
this....
});
Module("app", []).provider("serviceName",function(){
var enable = false;
return{
setEnable : function(value){enable=value}
$get : function(){
return {process : function{enable}}
}
}
});
-- 这三个方法指定的都是服务名
-- service - 一个构造函数,return一个服务实例,也可以作用基类,使用原型链扩展
-- factory - 一个服务工厂函数,return一个服务实例
-- provider - 一个provider工厂函数,使用 “服务名+Provider” 获取provider实例,在config函数中调用“serviceProvder”实例的方法进行配置,也可以在其他任何地方配置, 在依赖注入使用服务名时,provder会return一个服务实例
其实provider工厂函数就是js的闭包,来实现封装,配置信息,可以通过返回的provder的方法进行配置信息的读取和修改,angularjs会通过调用provider的$get方法返回provider
========================
-- 服务是单实例,推荐是在config阶段进行配置,其实任何地方修改了服务的配置,影响的是全局服务对象的使用
-- Value和Constant的依赖注入,Module("app", []).constant("const", "110") ; Module("app", []).value("val", "110") ,这样就可以controller的工厂函数中注入他们
-- 新手常见的错误就是将在JS的window对象下定义的变量,用于直接注入controller的工厂函数,AngularJs无法根据变量名无法找到由Angularjs注册的值或者常量,就会报错
-- 如果真要直接使用window对象下的全部变量,根据JS的函数作用域链,可以直接在工厂函数中使用该全局变量,无需在工厂函数中声明依赖,这样反而会报错,但是直接使用全局变量是单元测试变得困得不推荐这样使用
-- 推荐做法是使用到的任何值对象都应该由AngularJS声明,使用依赖注入方式来使用
6. controller组织方法及作用域继承
-- 在功能对应的同一模块下
-- $rootScope作用是最顶层的作用域
-- 通过ng-controller来确定
-- 只有一个controller的应用
-- 由多个并列同级的controller,可通过$rootScope作用域广播事件,在各自的作用注册事件,用于数据的同步通信
-- 一个controller下包含另一个controller,子controller同样再可以包含子controller,子作用域继承父作用域的数据
$rootScope
Mode -> Service(多条MVC的横切面) -> Controller($Scope -1 == VM) -> View
Mode -> Service(多条MVC的横切面) -> Controller($Scope -2 == VM) -> View
Mode -> Service(多条MVC的横切面) -> Controller($Scope -3 == VM) -> View
7. ng-mode:
-- 前提ng-mode绑定的数据是在父作用域定义,未在子作用域定义
-- 普通类型数据-在读取数据A用于显示时会从当前作用域逐层向上寻找,在更新数据A时,如果未在当前作用域发现,会在当前作用域内创建一个隐藏的数据A,并不会逐级向上寻找
-- 对象引用类型-所绑定的对象实际上仍然是子作用域从父作用继承而来的,并不会再当前作用域生成新的对象,对象是地址引用
8.指令作用域继承及隔离作用域
9.Route的controller及懒加载
10.过滤器filter
过滤器是将数据在被指令显示前进行格式化或者排序,而不会对原数据源进行修改
-- AngularJS已经提供了一些内置过滤器
内置指令服务
内置AngularJS方法
代码分包方法
-- 方式一,可以将module单独放到一个js文件,controller单独放到一个js文件,自定义指令单独放到一个js文件,过滤器单独放到一个js文件,路由单独放到一个js文件
a.通过jsp页面上