Angular

理解Directive中各个方法的执行顺序

Directive 在angular中扮演着非常重要的角色,而且对新手来说了使用起来也比较复杂。所以有必要来对 directive 做一个详细的分析,本片文章只来谈一下Directive中各个方法的执行顺序。

  • 先看下面的比较完整的Directive代码:

    app.directive("simple", function(){
       return {
         restrict: "E",
         template:"<div></div>",
         controller: function(scope, element, attributes){
           console.log("controller");
         },
         compile: function(element, attributes){
           console.log("compile");
           return {
               pre: function(scope, element, attributes, controller, transcludeFn){
                 console.log("pre");
               },
               post: function(scope, element, attributes, controller, transcludeFn){
                 console.log("post");
               }
           }
         }
       };
    });
    
  • controller, compile, pre 和 post 的执行顺序如下:
    1.compile (只会执行一次, 此过程是用来编译template, 但是不会执行渲染)
    2.controller (不执行渲染)
    3.pre (不执行渲染)
    4.post (执行渲染)

  • 其他关于Directive的详细讲解请看下面链接:

angular中自定定义服务service的方法以及比较

  • 第一种 provider 方法

    • 需要实现 this.$get 方法,并且此方法返回一个对象
    • Providers 是唯一一种你可以传进 .config() 函数的 service。当你想要在service对象启用之前,先进行模块范围的配置,那就应该用 provider
    • 所有的provider都可以通过在后面添加后缀Provider串来传进.config().
      • 比如一个叫 xxx provider service, 需要写成 xxxProvider .
    • 写法如图:
  • 第二种 factory 方法

    • Factory 方法直接把一个函数当成一个对象的 $get 方法, 可以直接返回字符串
    • 用 Factory 就是创建一个对象,为它添加属性,然后把这个对象返回出来。你把 service 传进 controller 之后,在 controller 里这个对象里的属性就可以通过 factory 定义的 service 使用了。
    • 写法如图:
  • 第三种 service 方法

    • Service 是用”new”关键字实例化的。因此,你应该给”this”添加属性,然后 service 返回”this”。你把 service 传进 controller 之后,在controller里 “this” 上的属性就可以通过 service 来使用了.
    • 写法如图:

angular的性能分析

我从2013年9月份开学习并在项目中使用 Angular, 期间遇到一些新能问题,特别是加载大数据的时候,性能明显慢下来了,当时用的还是Angular-1.0.4版本的。下面我就Angular-1.0.x版本谈下我发现的几个性能问题。

  • $watch 的实现原理和性能分析
    • 只有双向绑定的scope才会被加入$watch队列,或者手动绑定$watch的$scope
    • 所有放在$scope中的变量或函数都被加入到了$watch队列当中,每次只要$scope中的一个变量的值发生变化,Angular就会自动调用$apply或者$digest来把所有在$watch队列中的变量或函数都执行一遍,然后把当前值和上一次的值就行比较,如果有变化,就会在执行一遍(一直循环,最多11次),知道没有变化就会停止
    • 任何事件如果调用Angular的context中的函数之后,都会对$watch队列进行对比执行,不管有没有对$scope进行改变,例如:ng-click 执行了一个函数 $scope.say = function(){ \noing },在这个函数里面没有任何操作,但还是会执行$watch队列
  • ng-repeat 的原理和性能问题
    • 在ng-repeat循环中的每一个item都会建立一个单独的scope并对每个scope中的model进行$watch. 这样的话如果有200条数据,每条数据中5个属性要被$watch, 那么就是 200 * 5次,又因为每次脏数据检测至少都需要执行两次来保证所有变化都被应用,那么就是 200 * 5 * 2, 在加上单独的 ng-repeat一个和其他的model为n个,就是 200 * 5 * 2 + 1 + n, 如果这个数据超过2500的话页面就会变得很慢了
    • 所以如果ng-repeat的数据如果只是用来展示不需要对其进行操作的话就可以取消$watch绑定,可以使用一个Angular的第三方directive: Bindonce.

据说 Angular2.0 即将要发布了,跟之前的版本相比是一次革命性的改变。

Angular之$compile函数的使用

  • Angular之$compile函数的使用

    在用Angular写一些比较复杂的功能的时候,难免会遇到这样的需求:需要懂动态的往页面中插入一些元素,而且这些元素还需要跟scope中的的某些值绑定。

    比如要将一个div动态的插入到body中,如下:

    scope.attr = "hello";
    $("body").append('<div ng-bind="attr"></div>');
    

    但是如果只是上面这么写的话,不管你scope.attr怎么变化, div的html都不会有变化。那么怎么才能让它们绑定到一起的呢?这就要用到$compile函数了。

  • $compile函数的作用
    $compile函数可以将一段html字符串或者DOM元素跟scope编译绑定到一起。

  • $compile函数如何使用

    $compile(element)(scope);
    //element可以是一段html字符串,也可以是DOM元素;return值为编译完后的DOM元素
    
  • 用$compile完成上面的需求

    scope.attr = "hello";
    var html = $compile('<div ng-bind="attr"></div>')(scope);
    $("body").append(html);
    scope.$digest();//遍历scope