AngularJs应用现在越来越流行了,谷歌都与微软合作支持AngularJS2.0,这是要逆天了,说明AngularJs将来大势所趋。最近想跳槽,又重新拾起了AngluarJs(之前由于缺少项目应用,一直都是学了就忘记了),也写写复习的知识点,希望这次能让我对AngularJs的理解更深入透彻。

知识概要

一、什么是指令Directive

二、指令的编译过程及命名方式

二、AngularJS自定义指令的配置参数

二、AngularJS的内置指令有哪些

什么是指令Directive

  AngularJS指令使我们用来扩展浏览器能力的技术之一。在DOM编译期间,和HTML关联着的指令会被检测到,并且被执行。这使得指令可以为DOM指定行为,或者改变它。本质上就是AngularJS扩展具有自定义功能的HTML元素的途径。

  AngularJS有一套完整的、可扩展的、用来帮助web应用开发的指令集,它使得HTML可以转变成“特定领域语言(DSL)”。

指令的编译过程与命名方式

  在开始自定义指令之前,我们有必要了解一下指令在框架中的执行流程。如下:

  1.浏览器得到 HTML 字符串内容,解析得到 DOM 结构。

    你需要认清这一点,因为我们的模板必须是可被解析的HTML。这是AngularJS和那些“以字符串为基础而非以DOM元素为基础的”模板系统的区别之处。

  2.ng 引入,把 DOM 结构扔给 $compile 函数处理:
    ① 找出 DOM 结构中有变量占位符

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

    ③ 把指令关联到 DOM

    ④ 关联到 DOM 的多个指令优先级排列

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

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

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

  通过调用链接函数来将模板与作用域链接起来。这会轮流调用每一个指令的链接函数,让每一个指令都能对DOM注册监听事件,和建立对作用域的的监听。这样最后就形成了作用域的DOM的动态绑定。任何一个作用域的改变都会在DOM上体现出来。

  这里注意区别一下$compile和compile,前者是ng内部的编译服务,后者是指令中的编译函数,两者发挥作用的范围不同。compile和link函数息息相关又有所区别。了解执行流程对后面的理解会有帮助。

  理解一下编译函数与链接函数:

  编译函数 - 编译函数在指令中是很少的, 因为大部分指令都只是为了处理相应的DOM元素实例,而不是改变模板DOM元素。考虑到性能问题,任何指令的实例见能被共享的操作都应该移到编译函数中。

  链接函数 - 指令很少不带有链接函数,链接函数可以让指令对相应克隆元素注册事件,还可以将作用域中的内容复制到DOM中。

  指令的几种使用方式如下:

    作为标签:<my-dir></my-dir>

    作为属性:<span my-dir="exp"></span>

    作为注释:<!-- directive: my-dir exp -->

    作为类名:<span class="my-dir: exp;"></span>

    关于选择以哪一种方式指令,建议坚持使用属性方式,因为它有较好的跨浏览器兼容。

    关于自定义指令的命名,我们是可以随意命名的。注意,所有内置指令的命名空间都使用ng作为前缀。为了防止命名空间冲突,不要在自定义指令前加ng前缀。另外一个需知道的地方,指令命名时用驼峰规则,使用时用-分割各单词。如:定义myDirective,使用时像这样:<my-directive>。也建议大家写指令时,统一以my-打头做好规范,易于区分。

AngularJS自定义指令的配置参数

myModule.directive('namespaceDirectiveName', function factory(injectables) {

        var directiveDefinitionObject = {

            restrict: string,//指令的使用方式,包括标签,属性,类,注释

            priority: number,//指令执行的优先级   如果有ng-init定义了,则它优先级最高

            template: string,//指令使用的模板,用HTML字符串的形式表示

            templateUrl: string,//从指定的url地址加载模板

            replace: bool,//是否用模板替换当前元素,若为false,则append在当前元素上

            transclude: bool,//是否将当前元素的内容转移到模板中

            scope: bool or object,//指定指令的作用域

            controller: function controllerConstructor($scope, $element, $attrs, $transclude){...},//定义与其他指令进行交互的接口函数

            require: string,//指定需要依赖的其他指令

            link: function postLink(scope, iElement, iAttrs) {...},//以编程的方式操作DOM,包括添加监听器等

            compile: function compile(tElement, tAttrs, transclude){

                return: {

                    pre: function preLink(scope, iElement, iAttrs, controller){...},

                    post: function postLink(scope, iElement, iAttrs, controller){...}

                }

            }//编程的方式修改DOM模板的副本,可以返回链接函数

        };

        return directiveDefinitionObject;

});

  Directive Definition Object 指令定义对象标准解释:

  指令定义对象给编译器提供了生成指令需要的细节。这个对象的属性有:

  名称name - 当前作用域的名称,在注册是可选的。

  优先级priority - 当一个DOM上有多个指令时,有会需要指定指令执行的顺序。 这个优先级就是用来在执行指令的compile函数前先排序的。高优先级的先执行。 相同优先级的指令顺序没有被指定谁先执行。

  终端terminal - 如果被设置为true,那么该指令就会在同一个DOM的指令集和中最后被执行。任何其他“terminal”的指令也仍然会执行,因为同级的指令顺序是没有被定义的。

  作用域scope- 如果被定义成:

  那么就会为当前指令创建一个新的作用域。如果有多个在同一个DOM上的指令要求创建新作用域,那么只有一个新的会被创建。 这一创建新作用域的规则不适用于模板的根节点,因为模板的根节点总是会得到一个新的作用域。

    {} 对象哈希 - 那么一个新的“孤立的”作用域就会被创建。这个“孤立的”作用域区别于一般作用域的地方在于,它不会以原型继承的方式直接继承自父作用域。这对于创建可重用的组件是非常有用的,因为可重用的组件一般不应该读或写父作用域的数据。 这个“孤立的”作用域使用一个对象哈希来表示,这个哈希定义了一系列本地作用域属性, 这些本地作用域属性是从父作用域中衍生出来的。这些属性主要用来分析模板的值。这个哈希的键值对是本地属性为键,它的来源为值。

    @ 或 @attr - 将本地作用域成员成员和DOM属性绑定。绑定结果总是一个字符串,因为DOM的属性就是字符串。如果DOM属性的名字没有被指定,那么就和本地属性名一样。比如说<widget my-attr="hello {{name}}"> 和作用域对象: { localName:'@myAttr' }。当name值改变的时候, 作用域中的LocalName也会改变。这个name是从父作用域中读来的(而不是组件作用域)。

    = 或 =expression(表达式) - 在本地作用域属性和父作用域属性间建立一个双向的绑定。如果没有指定父作用域属性名称,那就和本地名称一样。 比如 <widget my-attr="parentModel"> 和作用域对象: { localModel:'=myAttr' }, 本地属性localModel会反映父作用域中parentModel的值。localModel和parentModel的任一方改变都会影响对方。

    & 或 &attr - 提供了一种能在父作用域下执行表达式的方法。如果没有指定父作用域属性名称,那就和本地名称一样。 比如 <widget my-attr="count = count + value">和作用域对象:{ localFn:'increment()' }。本地作用域成员localFn会指向一个increment表达式的函数包装。通常你可以通过这个表达式从本地作用域给父作用域传值, 操作方法是将本地变量名和值得对应关系传给这个表达式的包装函数。比如说,这个表达式是increment(amount),那么你就可以用调用localFn({amount:22})的方式指定amount的值。

  控制器controller - 控制器的构造对象。这个控制器函数是在预编译阶段被执行的,并且它是共享的,其他指令可以通过它的名字得到(参考依赖属性[require attribute])。这就使得指令间可以互相交流来扩大自己的能力。会传递给这个函数的参数有:

    $scope - 当前元素关联的作用域。
    $element - 当前元素
    $attrs - 当前元素的属性对象。
    $transclude - 模板链接功能前绑定到正确的模板作用域:function(cloneLinkingFn)。
  请求require - 请求将另一个控制器作为参数传入到当前链接函数。 这个请求需要传递被请求指令的控制器的名字。如果没有找到,就会触发一个错误。请求的名字可以加上下面两个前缀:

    ? - 不要触发错误,这只是一个可选的请求。
  ^ - 没找到的话,在父元素的controller里面也查找有没有。
  限制restrict - EACM中的任意一个之母。它是用来限制指令的声明格式的。如果没有这一项。那就只允许使用属性形式的指令。

      E - 元素名称:<my-directive></my-directive>
      A - 属性: <div my-directive="exp"> </div>
      C - 类名:<div class="my-directive: exp;"></div>
      M - 注释: <!-- directive: my-directive exp -->
    模板template - 将当前的元素替换掉。 这个替换过程会自动将元素的属性和css类名添加到新元素上。更多细节请查考章节“创建widgets”。

    模板templateUrl - 和template属性一样,只不过这里指示的是一个模板的URL。因为模板加载是异步的,所有编译和链接都会等到加载完成后再执行。

  替换replace - 如果被设置成true那么现在的元素会被模板替换,而不是被插入到元素中。

  编译模板transclude - 将元素编译好,使得指令可以开始使用它。一般情况下需要和ngTransclude指令一起使用。 使用嵌入的好处在于链接好书可以获取到预绑定在作用域上的函数。在一个典型的初始化过程中,widget会创建一个孤立的作用域,但是嵌入并不是其中一个子成员,而是这孤立作用域的兄弟成员。这使得widget可以有一个私有的状态,并且嵌入被绑定在父作用于上。

    true - 嵌入指令的内容。
    'element' - 嵌入整个元素,包括优先级较低的指令。
  编译compile - 这就是后面将要讲到的编译函数。

  链接link - 这就是后面将要讲到的链接函数。只有没有提供编译函数时才会用到这个值。

  指令这块确实知识点比较多,也是angularJS中很重要的一部分。

AngularJS内置指令

  所有的内置指令的前缀都为ng,不建议自定义指令使用该前缀,以免冲突。
  首先从一些常见的内置指令开始。
  先列出一些关键的内置指令,顺便简单说说作用域的问题。 

  ng-model
  将表单控件和当前作用域的属性进行绑定,这么解释似乎也不太正确。

  ng-init
  该指令被调用时会初始化内部作用域。

  ng-app
  每一次用AngularJS都离不开这个指令,顺便说下$rootScope。
  声明了ng-app的元素会成为$rootScope的起点,而$rootScope是作用域链的根,通常声明在<html>你懂的。
  也就是说根下的作用域都可以访问它。
  但是,不建议过度使用$rootScope,免得全局变量满天飞,效率又差又难管。 

  ng-controller
  我们用这个指令在一个DOM元素上装上controller。

  ng-disabled
  像这种只要出现则生效的属性,我们可以在AngularJS中通过表达式返回值true/false令其生效。
  禁用表单输入字段。

  ng-readonly
  通过表达式返回值true/false将表单输入字段设为只读

  ng-checked
  标准的checked属性是一个布尔属性,不需要进行赋值。通过ng-checked将某个表达式同是出现checked属性进行绑定。

  ng-select

  ng-select可以对是否出现option标签的selected属性进行绑定。

  ng-herf

  当使用当前作用域中的属性动态创建url时,应该用ng-href代替href

  ng-src

  angularJs会告诉浏览器呢在ng-src对应的表达式生效之前不要假装图像。

  ng-include

  使用ng-include可以加载、编译包括外部HTML片段到当前的应用中。

  ng中的事件绑定相关指令

  ng-change    ng-click    ng-dbclick    ng-mouseenter      ng-mouseleave     ng-mousemove   ng-mouseover  ng-mouseup

AngularJs指令(一)的更多相关文章

  1. AngularJS指令

    1. AngularJS指令的特点: AngularJS通过被称为指令的新属性来扩展HTML,指令的前缀为ng-. AngularJS通过内置的指令来为应用添加功能. AngularJS允许你自定义指 ...

  2. angularjs指令参数transclude

    angularjs指令参数transclude transclude翻译为嵌入,和之前看到的vue中的slots作用差不多,目的是将指令元素的子内容嵌入到指令的模板中 定义指令 <div sid ...

  3. angularjs 指令—— 绑定策略(@、=、&)

    angularjs 指令—— 绑定策略(@.=.&) 引入主题背景:angular 的指令配置中的template可以直接使用硬编码写相应的代码,不过也可以根据变量,进行动态更新.那么需要用到 ...

  4. AngularJS 指令

    AngularJS 指令 AngularJS 指令是扩展的 HTML 属性,带有前缀 ng-. ng-app 指令 ng-app 指令定义了 AngularJS 应用程序的 根元素. ng-app 指 ...

  5. angularjs指令(二)

    最近学习了下angularjs指令的相关知识,也参考了前人的一些文章,在此总结下. 欢迎批评指出错误的地方.   Angularjs指令定义的API AngularJs的指令定义大致如下 angula ...

  6. angularJs指令执行的机制==大概的三个阶段

    第一阶段:加载阶段 angularJs要运行的话,需要去等待angular.js加载完成,加载完之后呢,angular就会去查找到ng-app这个指令,ng-app在每个应用里面只能出现一次, 它也就 ...

  7. AngularJS学习笔记二:AngularJS指令

    AngularJS 指令: AngularJS 通过被称为 指令 的新属性来扩展 HTML. AngularJS 指令是扩展的 HTML 属性,带有前缀 ng-. 几个常用 指令: ng-app 指令 ...

  8. 【转】angularjs指令中的compile与link函数详解

    这篇文章主要介绍了angularjs指令中的compile与link函数详解,本文同时诉大家complie,pre-link,post-link的用法与区别等内容,需要的朋友可以参考下   通常大家在 ...

  9. AngularJS指令进阶 – ngModelController详解

    AngularJS指令进阶 – ngModelController详解 在自定义Angular指令时,其中有一个叫做require的字段,这个字段的作用是用于指令之间的相互交流.举个简单的例子,假如我 ...

随机推荐

  1. 数据库:mongodb与关系型数据库相比的优缺点

      与关系型数据库相比,MongoDB的优点:①弱一致性(最终一致),更能保证用户的访问速度:举例来说,在传统的关系型数据库中,一个COUNT类型的操作会锁定数据集,这样可以保证得到“当前”情况下的精 ...

  2. 联想硬盘分区表格式修改 GPT -> MBR

    知识点分析:随机预装Win8的电脑,磁盘为GPT格式的,如果需要安装Win7等早期版本系统,需要转换为MBR格式的,使用Diskpart命令即可完成转换. 操作步骤: 注意:转换磁盘格式需要清空磁盘中 ...

  3. EasyUI Accordion下的Panel面板初始化时全部折叠

    EasyUI Accordion下的Panel面板有一个属性:selected,默认值为:false.初始化时,若设置'selected:true',则面板默认打开,效果如下: <div tit ...

  4. web前端—工作周报

    2016.07.25-2016.07.29周报: 1.本周工作主要内容: A:完成了宏视云h5播放器升级及大数据上报: B:修复xk-h5播放器bug:在三星手机自带浏览器无法进行滑动seek;  C ...

  5. jQuery实现的瀑布流效果, 向下滚动即时加载内容

    下拉滚动条或鼠标滚轮滚动到页面底部时, 动态即时加载新内容. 后台用 json 传输数据, 示例程序中只写了示例数组.数据也只设置了两个属性, 需根据实际应用改写.   页面用了 ul li 做为容器 ...

  6. hihocoder #1179 : 永恒游戏 暴力

    #1179 : 永恒游戏 Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://hihocoder.com/problemset/problem/11 ...

  7. C#缩放和裁剪图片

    在GDI+中,缩放和剪裁可以看作同一个操作,无非就是原始区域的选择不同罢了.空口无凭,先看具体算法可能更好理解. using System; using System.Collections.Gene ...

  8. ajax开发框架和XMLhttpRequest、responseText、responseXml和JSON的应用

    1 AJAX开发框架 2 A 初始化XMLHttpRequest对象 3 B指定响应处理函数 4 C发出HTTP请求 5 D处理服务器返回的信息 6 数据格式提要 6 优点 6 缺点 7 解析 JSO ...

  9. Memcached概述

    Memcached Memcached是一套分布式的内存对象缓存系统,使用C语言编写,作为数据库的前端cache,缓存数据库查询结果能够减轻数据库负载. 类似一张巨大的hash表,缓存的对象以key- ...

  10. 云服务器 ECS Linux 误删除文件恢复方法介绍

    云服务器 ECS Linux 下,rm -rf  意味着一旦删除的文件是无法挽回的.但如果在没有文件覆盖操作的前提下,可以先尝试相关方式进行文件恢复. 本文对此进行简要说明. https://help ...