美文网首页我爱编程
**Angular** 笔记

**Angular** 笔记

作者: 神刀 | 来源:发表于2018-01-05 10:28 被阅读51次

    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()

    相关文章

      网友评论

        本文标题:**Angular** 笔记

        本文链接:https://www.haomeiwen.com/subject/ggujnxtx.html