**Angular** 笔记

Angular 笔记

Angularjs 中 ui-sref 和 $state.go 如何传递参数

ng-repeat

[

[{},{}],

[{},{}],

[{},{}]

]

<tbody ng-repeat="t in vm.detailData track by $index" style="border:0">

<tr ng-repeat="i in t track by $index">

<td rowspan="{{i.length}}" ng-show="($index) % i.length == 0">{{i.date}}</td>

<td>{{i.platform}}</td>

</tr>

</tbody>

$apply()与 $digest()以及$Watch()

$watch 队列?

每绑定UI,就往watch队列里插入一条$watch, $watch监视model变化

$digest 循环?

包含两个循环,一个循环evalAsync队列,一个循环$watch队列;

dirtychecking(脏检测)?

$digest循环一遍所有$watch,会再循环一次确认无改变;超过10次会抛出异常,防止无限循环;

$apply ?

事件绑定:ng-click=fn() 相当于$scope.$apply(function(){fn)}) // fn() 被自动传递给$apply()包裹一层;$apply() 默认调用 $rootScope.$digest()

双向绑定:ng-model="foo"的输入框,然后你敲一个f,事件就会这样调用$apply("foo = 'f';")

=>start

  1. 游览器接受一个angular支持的事件 =>
  2. 调用$apply =>
  3. 进入angular 上下文 =>
  4. 执行$digest循环 =>
  5. 再$digest(无变化) =>
  6. 回到游览器上下文,更新dom

<= end

ng-repeat高级

遍历数组:<li ng-repeat="item in array">{{item}}</li>

遍历对象:<li ng-repeat="(key,value) in obj">{{key}} | {{value}}</li>

绑定$$haskKey:

给每个item绑定唯一ID,当数组发生变化时,ID不变!

<li ng-repeat="item in items track by $id(item)"></li>

过滤器:

对item的每个属性进行模糊匹配

 <li ng-repeat="item in items |filter: 25"></li>

绑定属性过滤:

对item的某个属性进行模糊匹配

<li ng-repeat="item in items |filter: 25 track by item.age"></li>

保存匹配结果:

把匹配到的结果另存到results数组变量,可供外部使用

<li ng-repeat="item in items |filter: 25 as results"></li>

保存针对某个属性的过滤结果:

<li ng-repeat="item in items |filter: 25 as results track by item.age "></li>

路由传参:

'Root.Offer.EventInfo': {

url: '/EventInfo/:id',

},

'Root.Finance_adv.InvoiceDetail': {

url: '/Invoice/Detail?id&READ',

},

ui-sref="Root.Offer.EventInfo({id:item.id})

ng-model

ngModelController中两个管道数组 $formatters 和 $parsers

$formatters :将Model数据转换为view视图显示的值

$parsers: 将交互控件的view值转换为Model格式的数据

ngModelCtrl.$parsers.push(function(value) {…});

ngModelCtrl.$formatters.push(function(value) {...});

ng-class

ng-class="{true: 'active', false: 'inactive'}[isActive]" //isActive表达式为true,则 active,否则inactive

ng-class = “{‘selected': isSelected, 'car': isCar}" //当 isSelected = true 则增加selected class,

当isCar=true,则增加car class,

ng 原理分析:

脏检测机制的低效

只要变过数据,至少要跑两次脏检测

模块机制

$scope 对象

是一个js 的 POJO

有两个特别的函数:$watch 、$digest

DI 实现原理

在使用模块时无需require()引入,直接通过形参注入到函数所在作用域

js实现DI

angular DI:

ng笔记:

七、模版:

#模版内容:

三种方式:字符串;外部文件,script定义内部文件

ng-include src=“ ‘’ ”

ng-include=“ ‘’ ”

<script type="text/ng-template" id="tpl">here, {{ 1 + 1 }}</script>

<div ng-include src="'tpl'"></div>

渲染控制

节点控制

ng-style

ng-class

ng-show | ng-hide | ng-switch

ng-src

ng-href

数据绑定:

  • ng-src src属性
  • ng-href href属性
  • ng-checked 选中状态
  • ng-selected 被选择状态
  • ng-disabled 禁用状态
  • ng-multiple 多选状态
  • ng-readonly 只读状态

事件绑定 (事件对象 $event $event.target)

  • ng-change
  • ng-click
  • ng-dblclick
  • ng-mousedown
  • ng-mouseenter
  • ng-mouseleave
  • ng-mousemove
  • ng-mouseover
  • ng-mouseup
  • ng-submit

表单控件

from 动态类:

  • ng-valid 当表单验证通过时的设置
  • ng-invalid 当表单验证失败时的设置
  • ng-pristine 表单的未被动之前拥有
  • ng-dirty 表单被动过之后拥有

form 对象的属性有:

  • $pristine 表单是否未被动过
  • $dirty 表单是否被动过
  • $valid 表单是否验证通过
  • $invalid 表单是否验证失败
  • $error 表单的验证错误

input 相关可用属性为:

  • name 名字
  • ng-model 绑定的数据
  • required 是否必填
  • ng-required 是否必填
  • ng-minlength 最小长度
  • ng-maxlength 最大长度
  • ng-pattern 匹配模式
  • ng-change 值变化时的回调
  • input type="number" 多了 number 错误类型,多了 max , min 属性。
  • input type="url" 多了 url 错误类型。
  • input type="email" 多了 email 错误类型。
  • checkbox 选中ng-true-value="AA" 不选中ng-false-value="BB"
  • radio value=“aa”
  • select ng-options [数组、对象]

八、过滤器

内置过滤器

1. currency (货币处理) 人民币:{{num | currency : ‘¥’}};默认是美元

2. date (日期格式化) {{date | date : 'yyyy-MM-dd hh:mm:ss EEEE'}}

y M d h m s E 表示 年 月 日 时 分 秒 星期,描述性字符串:“shortTime”将会把时间格式为12:05 pm

3. filter(匹配子串)

$scope.childrenArray = [{name:'shitou',age:6},{name:'tiantian',age:5}];

$scope.func = function(e){return e.age>4;}

{{ childrenArray | filter : 'a' }} //匹配属性值中含有a的

{{ childrenArray | filter : {name : 'i'} }} //参数是对象,匹配name属性中含有i的

{{childrenArray | filter : func }} //参数是函数,指定返回age>4的

4. json(格式化json对象) 格式化为json字符串,和JSON.stringify()一样

5. limitTo(限制数组长度或字符串长度) {{ childrenArray | limitTo : 2 }} //将会显示数组中的前两项

6. lowercase(小写)

7. uppercase(大写)

8. number(格式化数字) //默认加上千位123,456,789。接收参数指定保留小数位 {{ num | number : 2 }}

9. orderBy(排序)

参数为字符串,表示以该属性名称进行排序。

参数为函数,定义排序属性。

参数为数组,表示依次按数组中的属性值进行排序(若按第一项比较的值相等,再按第二项比较)

<div>{{ childrenArray | orderBy : 'age' }}</div> //按age属性值进行排序,若是-age,则倒序

<div>{{ childrenArray | orderBy : orderFunc }}</div> //按照函数的返回值进行排序

<div>{{ childrenArray | orderBy : ['age','name'] }}</div> //如果age相同,按照name进行排序

自定义过滤器

使用module的filter方法,返回一个函数,该函数接收输入值,并返回处理后的结果。

比如我需要一个过滤器,它可以返回一个数组中下标为奇数的元素,代码如下:

app.filter('odditems',function(){

return function(inputArray){

var array = [];

for(var i=0;i<inputArray.length;i++){

if(i%2!==0){

array.push(inputArray[i]);

}

}

return array;

}

});

处理逻辑就写在内部的闭包函数中。你也可以让自己的过滤器接收参数,参数就定义在return的那个函数中,作为第二个参数,或者更多个参数也可以。

九、路由

十、定义模版变量标识符

十一、Ajax

$http

$q

十二、工具函数

angular.bind()

angular.copy()

angular.extend()

空函数: angular.noop()

大小写转换: angular.lowercase()和 angular.uppercase()

JSON转换: angular.fromJson()和 angular.toJson()

遍历: angular.forEach(),支持列表和对象

类型判定

  • angular.isArray
  • angular.isDate
  • angular.isDefined
  • angular.isElement
  • angular.isFunction
  • angular.isNumber
  • angular.isObject
  • angular.isString
  • angular.isUndefined

十三、其它服务

日志 $log

缓存 $cacheFactory

计数器 $timeout $timeout.cancel()取消

表达式函数化 $parse

模版单独使用 $compile

十四、自定义模块与服务

ng模块(默认模块):提供$http,$q等服务

模块提供包括:服务、指令、过滤器、及其他配置信息等机制

使用时,模块需要显示声明依赖,服务可以通过ng自动注入

自定义服务:

provider对象 :被“注入控制器”使用的一个对象 注入机制通过provider.$get(),把得到的东西作为参数进行相关调用

eg:把得到的服务作为一个controller 的参数

底层方法:

$provider.provider(‘pp’, function(){this.$get = ()=>{‘haha’:’1234’}})

//定义一个叫pp的服务,pp服务也就是pp这个provider的get()返回的东西

factory 返回object

$provider.factory(‘pp’, function(){return {}})

app.factory('PP', function(){return {'abc': '123'}});

service 可以是数字、字符串

app.service('PP', function(){this.abc = '123';});

provider

1. 为应用提供通用的服务,形式可以是常量或对象

2. 便于模块化

3. 便于单元测试

provider可写成

$provide.provider('age', {

start: 10,

$get: function() {

    return this.start + 2;

}

});

//或

$provide.provider('age', function($filterProvider){

this.start = 10;

this.$get = function() {

    return this.start + 2;

};

});

//调用:

app.controller('MainCtrl', function($scope, age) {

$scope.age = age; //12

});

其原理是通过实现$get方法来在应用中注入单例,使用的时候拿到的age就是$get执行后的结果

factory可以写成

$provide.factory('myDate', function(){

return new Date();

});

service可写成

$provide.service('myDate', Date);

value & constant

区别一:****value****可以被修改,****constant****一旦声明无法被修改

1 $provide.decorator('pageCount', function($delegate) {

2 return $delegate + 1;

3 });

decorator可以用来修改(修饰)已定义的provider们,除了constant~

区别二:****value****不可在****config配置函数里注入,****constant****可以

1 myApp.config(function(pageCount){

2 //可以得到constant定义的'pageCount'

3 });

十五、附加模块 ngResource

十六、与其它框架混用

ng 最忌讳修改 DOM 结构——应该使用 ng 的模板机制进行数据绑定,以此来控制 DOM 结构,而不是直接操作。

数据使用哪个框架来控制都是没问题的,如有必要使用 $scope.$digest() 来通知 ng 一下即可

十七、自定义过滤器

filter 就是一个函数,虽然定义在module下,但无任何上下文关联的能力

app.filter('map', function(){

var filter = function(input){return input + '...'; };

return filter;

});

使用:{{ a|map}}

传参:{{ a|map:map_value:'>>':'(no)' }}

十八、自定义指令

指令返回一个对象 return{};返回return fn的话,fn将作为link函数使用

directive的执行过程:

  • 浏览器解析html字符串得到 DOM 结构

  • ng 引入,把 DOM 结构扔给 $compile 函数处理:

  • 找出 DOM 结构中有变量占位符

  • 匹配找出 DOM 中包含的所有指令引用

  • 把指令关联到 DOM

  • 关联到 DOM 的多个指令按权重排列

  • 执行指令中的 compile 函数(改变 DOM 结构,返回 link 函数)

  • 得到的所有 link 函数组成一个列表作为 $compile 函数的返回

  • 执行 link 函数(连接模板的 scope)。

  • 浏览器把 HTML 字符串解析成 DOM 结构。

  • ng 把 DOM 结构给 $compile ,返回一个 link 函数。

  • 传入具体的 scope 调用这个 link 函数。

  • 得到处理后的 DOM ,这个 DOM 处理了指令,连接了数据。

一个完整指令返回一个对象,包含compile、link、restrict等属性;

如果指令返回一个函数fn,则这个fn会作为compile的返回值,也即作为link函数使用;

指令包含的属性

  • name
  • priority
  • terminal
  • scope
  • controller
  • require
  • restrict
  • template
  • templateUrl
  • replace
  • transclude
  • compile
  • link

app.directive('color', function(){

var link = function($scope, $element, $attrs){

$scope.$watch($attrs.color, function(new_v){

$element.css('color', new_v);

});

}

return link;

});

compile的细节

基本形式

let link = $compile(‘<div></div>’); //返回link函数

let node = link($scope, cloneAttachFN);// cloneAttchFn表示是否复制原始节点以及对复制节点需要做的处理

注意:这里不能做数据绑定;因为{{ }}在 $compile 中已被处理过,生成了相关函数;后面执行 link 就是执行了 $compile 生成的这些函数。如果你的文本没有数据变量的引用,那修改是会有效果的。

link 函数是由 compile 函数返回的;应该把改变 DOM 结构的逻辑放在 compile 函数中做。

$compile另外两个参数:

$compile(element, transclude, maxPriority);

$compile

解析html模板

返回两个函数pre-link和post-link

先执行pre-link,从父节点到子节点遍历,在这个阶段,进行一些初始化数据的处理。

第二执行的是post-link,即link函数,从子节点到父节点遍历,在这个阶段,DOM节点已经稳定下来

$parse 服务

解析表达式,将一个表达式转换为一个函数

var getter = $parse('user.name');

var setter = getter.assign;

setter(scope, 'new name');

getter(context, locals) // 传入作用域,返回值 context含有你要解析语句中的表达式,通常为一个scope对象

setter(scope,'new name') // 修改映射在scope上的属性的值为‘new value’

$eval()方法

基于$parse, 作为scope的方法使用;scope.$eval('a+b'); 而这个里的a,b是来自 scope = {a: 2, b:3};

transclude

transclude:true //在指令中说明需要嵌入

ng-transclude //在模版中说明要嵌入的位置

取出自定义指令中的内容(就是写在指令里面的子元素),以正确的作用域解析它,然后再放回指令模板中标记的位置(通常是ng-transclude标记的地方),

注入服务

服务可以定义在任意模块,注入服务时需要引入所在的模块依赖;

link

link函数的$attrs 参数 : 指令元素的属性合集;

$attrs.$observe()方法: 监听属性变化,触发一个回调函数

$scope 的属性

$id: "002" scope唯一标示
$root: Scope 根scope

$parent: null 父scope

$$childHead: null 第一个子scope
$$childTail: null 最后一个子scope

$$prevSibling: null 上一个兄弟scope

$$nextSibling: null 下一个兄弟scope

$$phase: null
$$destroyed: false
$$isolateBindings: Object
$$listenerCount: Object
$$postDigestQueue: Array[0]
$$watchers: Array[1]

$$asyncQueue: Array[0]

////发布订阅事件模型 可在各级controller内传递event和data

$$listeners: Object 在scope上注册事件监听器

//原型继承.proto

$on(evt,fn(args)) 监听处理(名为evt,监听器为fn)

$emit(evt,args) 发送evt事件,冒泡;在当前scope及所有$parents上触发

$broadcast(eat,args) 发送事件eat,捕获;在当前scope及其所有children上触发

"$new",

"$watch",

"$watchCollection",

"$digest",

"$destroy",

"$eval",

"$evalAsync",

"$$postDigest",

"$apply",

constructor

指令的几种参数

内部参数 //描述指令或DOM本身特性的内部参数

restrict:String, E(元素) A(属性,默认值)C(类名) M(注释)

priority: Number, 指令执行优先级

template: String, 指令链接DOM模板,例如“<h1>{{head}}</h1>”
templateUrl:String, DOM模板路径
replace: Boolean, 指令链接模板是否替换原有元素

对外参数scope // scope是指令与外界作用域通讯的桥梁

scope:Boolean or Object 隔离指令与所在控制器间的作用域、隔离指令与指令间的作用域

false 共享父域(默认值);

true 继承父域且新建独立作用;

指令未申明scope.data时, 在指令中可监听父域data。父域变更,指令数据也会变更;但一旦指令中input变更了,指令独立scope也会自动绑定

指令已声明scope.data时,在指令中监听父域data无效。但可通过scope.$parent监听父域

{} 不继承父域且新建独立作用域()

对外参数require // require是指令与指令之间通讯的桥梁

require: String or Array 通过require参数,指令可以获得外部其他指令的控制器,从而达到交换数据、事件分发的目的

require: '^teacher1', 如果require为String,ctrl为对象,如果require是数组,ctrl为数组。

link: function ($scope, $element, $attrs, ctrl) { //ctrl参数指向teacher1指令的控制器}

?策略 寻找指令名称。如果找不到,link第4个参数为null。 假如无“?”则报错。

^ 策略 在自身指令寻找指令名称,同时向上父元素寻找。 假如没有“^”则仅在自身寻找。

行为参数link与controller //描述指令本身行为的行为参数 先controller,后link

controller: 控制器函数;定义指令内部作用域的行为

link 链接函数; 定义指令元素的操作行为

  1. 分析指令,加载模板,形成DOM模板树
  2. 执行link,设置DOM各个行为;从最底部指令开始依次执行指令的link函数(适合dom操作,性能开销最小,如鼠标操作或触控事件分发绑定、样式Class设置、增删改元素等等)
  3. 数据绑定(最后scope绑上DOM)

$watch()和$observe()

$watch()

scope对象的方法;推荐在指令的link函数中使用;
可以监测expression和函数的变化,它使用$parse将angular expression解析为一个函数,

这个函数会在angular的每个脏值检查循环中被调用。 $observe()

指令中link函数中实例属性即(iAttr)的方法。 只可以在指令的link函数中使用。 只监测angular expression的变化

异同:

$rootscope之所以被称为"root"的原因就是他是所有scope的祖先,$rootscope是在angular启动流程中建立的(上上期讲过),而被注入到controller中的$scope则是在视图创建的时候通过父辈的$scope.$new制造出来的,在视图销毁的时候,$scope会被跟着销毁。$scope是链接视图和controller的重要手段,controller则是可以与服务进行链接,将服务提供的功能进行组合,然后丢给$scope,$scope则将这些传递给视图,让它显示给用户。如果将一个$scope比作一个人的话,那么他的功能有:生育功能($new)、进食功能($watch)、消化功能($digest)、执行功能($apply)、交流功能($on、$emit、$broadcast)、死亡功能($destory)。

compile & link

只使用了一个link函数,那么ng会把这个函数当成post-link来处理

compile函数: 返回pre-link post-link

执行顺序: 先compile 再pre-link 再post-link

compile与pre-link函数: 顺序执行

post-link函数: 反序执行

module

  • _invokeQueue
    :
    Array[4]
    _runBlocks
    :
    Array[0]
    animation
    :
    ()config
    :
    ()constant
    :
    ()controller
    :
    ()directive
    :
    ()factory
    :
    ()filter
    :
    ()name
    :
    "PonyDeli"
    provider
    :
    ()requires
    :
    Array[0]
    run
    :
    (block)service
    :
    ()value
    :
    ()

$log 服务

debug()error()info()log()warn()

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,242评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,769评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,484评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,133评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,007评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,080评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,496评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,190评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,464评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,549评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,330评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,205评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,567评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,889评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,160评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,475评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,650评论 2 335

推荐阅读更多精彩内容