头部背景图片
senrenbankaの部落格 |
senrenbankaの部落格 |

《AngularJS深度剖析与最佳实践》学习笔记(一)

看了三章之后才想到我应该写一些笔记来加深印象和理解,所以写的顺序会有点乱,到时再进行重新排版

指令:

Angular2.0将指令分为组件型指令装饰器型指令,虽然是2.0的标准,但是这个分法同样适用于Angular1.0:

组件型指令:

组件型指令的一般格式如下:

angular.module('myApp').directive('conponent',function(){
      return {
        restrict: "EA",
        scope: {
            count:1
        },
        templateUrl: 'partials/conponent.html',
        controller: function($scope){
            //相关业务逻辑操作
        }
        ....
    }
});

组件型指令的特点可以概括为: 高内聚低耦合
这种指令通常作为页面或者模板的一个组件,有自己的独立作用域,形成自己的业务逻辑,与外部模板页面的耦合性低,即使去掉这个指令,也不会对全局有影响,这样带来的好处是:代码的可维护性和复用性;

我们搭建的组件可以用在其他的页面上,例如,我们做了个登录框的组件:

<login-form username='form.username' email="form.email' password='form.password'></login-form>

自定义指令:

angular.module('myApp').directive('loginForm',function(){
    return {
        restrict: 'EA',
        scope: {
            username: '=',
            email: '=',
            password: '='
        },
        templateUrl: 'partials/login.html',
        controller: function($scope,$http) {
            //业务逻辑处理
            $http({
                method:"POST"
                data: ''
            }).success(function(data) {
                //...
            });
        },
    }
});

这样,我们自定义的登录组件骨架基本完成,只要想在页面进行引用,就在模板页面嵌入对应的元素即可。

组件型指令是一个小型的,内聚的,自封装的整体,其主要的目的应是内容信息的展示,应该尽量避免使用link(初学者写自定义指令一般都会用到这个,并且在link阶段加入典型的jQuery代码,再用scope.$apply()通知ViewModel进行脏检查。。。不要问我为什么知道),
将业务逻辑写在controller中,当然,controller不要太脏,应该将表现层逻辑的代码用服务封装y,与业务层逻辑代码分离,保持controller的干净;

restrict

restrict中我们设为’EA’,retrict有四种情况:E(元素),A(属性),M(注释),C(类),通常我们在实战中用到比较多的是EA,
如果我们的定位为组件型指令而不是装饰器型指令,我们可以只用E,用A是为了与IE8兼容,因为IE8对于新元素必须要通过document.createElement去实现。。。,当然,不想兼容IE8就略过这点。。。

scope

scope在指令中有三种情况:
scope = undefined || false: 这种情况不需要创建作用域,直接使用父作用域的数据,如果节点中有创建了新作用域或独立作用域的指令,可以引用对应的作用域;
scope = true: 这种情况则是表示需要一个新作用域,可以共享节点的新作用域,如果没有,则自己创建一个新作用域;
scope = 哈希对象: 这种则是创建独立作用域,只通过某些固定的接口与外部作用域进行交互,实现了与外部作用域的隔离,这种情况我们即可以从父作用域获取我们想要的属性,又能避免引用到父作用域的相关属性;

当scope为哈希对象时,我们通常这样写:

scope: {
  count: '@',
  count1: '=',
  count2: '&'
}

@表示的是引用字符串,’=’表示的是引用父作用域的变量,’&’表示的是引用父作用域的方法;

装饰器型指令:

装饰器型指令的特点是: 给对应节点增添dom行为,增强view与model的同步;
不像组件型指令是作为一个整体,装饰器型指令的定位是作为功能性的连接器,增强相应的表现层和业务层逻辑,一般的定义方式如下:

angular.module('myApp').directive('decorator',function() {
    return {
        restrict: 'EA',
        link: function(scope,elm,attrs) {
            //.....
        }
     };
});

当然,上面的定义是最基本的,后面还要讲到一些关于指令的重要的东西,这里就先这样用。
装饰器型指令中,由于其定位关系,不像组件型指令,它并不需要创建新作用域或是独立作用域(当然如果你想创建也可以),那么,如果我们没有创建作用域,那我们是如何像独立作用域那样拿到赋予的值呢?

回到我们上面的代码,我们可以看到link参数有个attrs,嗯,这个就是我们获取数据的关键,看下面的代码:

<login-form username='feitou' email='form.email' password='form.password' submit='submit(time)'></login-form>

实际上不会写这样的指令,在这里只是作为说明使用———username对应的是固定字符串feitou,我们可以在link阶段直接用attrs.username获取这个字符串,父作用域的值则通过scope.$eval(attrs.email)获取,scope.$eval()负责计算表达式的值,而父作用域的方法呢?由于方法也是父作用域的一部分,所以我们依旧用scope.$eval(),但是要这样用(以上面为例):scope.$eval(attrs.submit',{ time:3 }),第二个参数就是传入方法的参数,用对象来配置,并且名字要对应相同(与view上的方法参数名对应相同),这样,我们讲解了没有作用域如何去获取对应的数据了;

angular内置的大多数指令如ng-hide,ng-show这样都是装饰器型的指令,就是增强html的功能,将view进行进一步的分离,在实战中,我们避免不了要写自定义指令,这个时候,我们要考虑的,是我们这个指令的定位是什么,根据我们的定位去选择对应的指令方式,代码结构才能不断优化,指令的目的之一,就是为了优化我们的代码结构。

avatar AONOSORA 今生今世轮回尽, 来世愿为幻想乡