`
liujiekasini0312
  • 浏览: 147309 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

走进AngularJs(三)自定义指令-----(上)

 
阅读更多

一、有感而发的一些话

  在学习ng之前有听前辈说过,angular上手比较难,初学者可能不太适应其语法以及思想。随着对ng探索的一步步深入,也确实感觉到了这一点,尤其是框架内部的某些执行机制,其复杂程度并非是我现在的功力能够理解的,只能是知其皮毛。我现在学习的途径是官方文档 + AngularJS在github上的中文粗译版(https://github.com/basestyle/angularjs-cn)+ 网上搜到的一些文章。鉴于本人资质平平以前也只用过jQuery,目前只能做到理解ng的API文档,相关特性的使用方式。故博客的主要内容也就是记载一些我的理解与应用,对ng框架内部的机制只做必要的了解,暂不深入探究。

  智商捉急,就到这里~

  接下来聊聊angular的指令机制。angular通过指令的方式实现了HTML的扩展,增强后的HTML就好比是究极进化后的暴龙兽,不仅长相焕然一新,同时也获得了很多强大的技能。更厉害的是,你还可以自定义指令,这就意味着HTML标签的范围可以扩展到无穷大,ng赋予了你造物主的能力。作为angular的精华之一,指令相关的知识也很多,本篇开始探索自定义指令的方方面面。为了不让我的篇幅再拉那么长,我识趣的在标题后面加了(上),你懂的。

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

  在开始自定义指令之前,我们有必要了解一下指令在框架中的执行流程。这部分内容我没有自己研究,只是照搬了别人的说法:

  1. 浏览器得到 HTML 字符串内容,解析得到 DOM 结构。
  2. ng 引入,把 DOM 结构扔给 $compile 函数处理:

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

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

    ③ 把指令关联到 DOM

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

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

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

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

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

  在这里我小小的多嘴一下,有些人可能会问,angular不就是一个js框架吗,怎么还能跟编译扯上呢,又不是像C++那样的高级语言。其实此编译非彼编译,ng编译的工作是解析指令啦,绑定监听器啦,替换模板中的变量啦这些。因为工作方式很像高级语言编辑中的递归、堆栈过程,所以起名为编译,不要疑惑。

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

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

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

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

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

  其实常用的就是作为标签和属性,下面两种用法目前还没见过,姑且留个印象。我们自定义的指令就是要支持这样的用法。

  关于自定义指令的命名,你可以随便怎么起名字都行,官方是推荐用[命名空间-指令名称]这样的方式,像ng-controller。不过你可千万不要用ng-前缀了,防止与系统自带的指令重名。另外一个需知道的地方,指令命名时用驼峰规则,使用时用-分割各单词。如:定义myDirective,使用时像这样:<my-directive>。

三、自定义指令的配置参数

  下面是定义一个标准指令的示例,可配置的参数包括以下部分:

复制代码
myModule.directive('namespaceDirectiveName', function factory(injectables) {

        var directiveDefinitionObject = {

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

            priority: number,//指令执行的优先级

            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;

});
复制代码

看上去好复杂的样子啊~定义一个指令需要这么多步骤嘛?当然不是,你可以根据自己的需要来选择使用哪些参数。事实上priority和compile用的比较少,template和templateUrl又是互斥的,两者选其一即可。所以不必紧张,接下来分别学习一下这些参数,我将先从一个简单的例子开始。为了易于理解和我以后翻看的时候还能看明白,我尽量使用有语义的命名,而不是像test1,test2这样。

例子的代码如下:

复制代码
var app = angular.module('MyApp', [], function(){console.log('here')});
app.directive('sayHello',function(){ return { restrict : 'E', template : '<div>hello</div>' }; })
复制代码

然后在页面中,我们就可以使用这个名为sayHello的指令了,它的作用就是输出一个hello单词。像这样使用:

<say-hello></say-hello>

这样页面就会显示出hello了,看一下生成的代码:

  

稍稍解释一下我们用到的两个参数,restirct用来指定指令的使用类型,其取值及含义如下:

取值

含义

使用示例

E

标签

<my-menu title=Products></my-menu>

A

属性

<div my-menu=Products></div>

C

<div class="my-menu":Products></div>

M

注释

<!--directive:my-menu Products-->

默认值是A。也可以使用这些值的组合,如EA,EC等等。我们这里指定为E,那么它就可以像标签一样使用了。如果指定为A,我们使用起来应该像这样:

<div say-hello></div>

从生成的代码中,你也看到了template的作用,它就是描述你的指令长什么样子,这部分内容将出现在页面中,即该指令所在的模板中,既然是模板中,template的内容中也可以使用ng-modle等其他指令,就像在模板中使用一样。

  在上面生成的代码中,我们看到了<div>hello</div>外面还包着一层<say-hello>标签,如果我们不想要这一层多余的东西了,replace就派上用场了,在配置中将replace赋值为true,将得到如下结构:

  

replace的作用正如其名,将指令标签替换为了temple中定义的内容。不写的话默认为false。

上面的template未免也太简单了,如果你的模板HTML较复杂,如自定义一个ui组件指令,难道要拼接老长的字符串?当然不需要,此时只需用templateUrl便可解决问题。你可以将指令的模板单独命名为一个html文件,然后在指令定义中使用templateUrl指定好文件的路径即可,如:

templateUrl : ‘helloTemplate.html’

系统会自动发一个http请求来获取到对应的模板内容。是不是很方便呢,你不用纠结于拼接字符串的烦恼了。如果你是一个追求完美的有考虑性能的工程师,可能会发问:那这样的话岂不是要牺牲一个http请求?

这也不用担心,因为ng的模板还可以用另外一种方式定义,那就是使用<script>标签。使用起来如下:

<script type="text/ng-template" id="helloTemplate.html">
         <div>hello</div>
</script>

你可以把这段代码写在页面头部,这样就不必去请求它了。在实际项目中,你也可以将所有的模板内容集中在一个文件中,只加载一次,然后根据id来取用。

接下来我们来看另一个比较有用的配置:transclude,定义是否将当前元素的内容转移到模板中。看解释有点抽象,不过亲手试试就很清楚了,看下面的代码:

复制代码
app.directive('sayHello',function(){
                   return {
                            restrict : 'E',
                            template : '<div>hello,<b ng-transclude></b></div>',
                            replace : true,
                            transclude : true
                   };
         })
复制代码

指定了transclude为true,并且template修改了一下,加了一个<b>标签,并在上面使用了ng-transclude指令,用来告诉指令把内容转移到的位置。那我们要转移的内容是什么呢?请看使用指令时的变化:

<say-hello>美女</say-hello>

内容是什么你也看到了哈~在运行的时候,美女将会被转移到<b>标签中,原来此配置的作用就是——乾坤大挪移!看效果:

  

这个还是很有用的,因为你定义的指令不可能老是那么简单,只有一个空标签。当你需要对指令中的内容进行处理时,此参数便大有可用。

四、结束

  看前面写的两篇,感觉篇幅太长了,可能会有人耐不住性子看完,故本篇先介绍几个比较简单的参数,先拿软的来捏一捏,更复杂的用法还在后头。我们将真正用一下自定义指令,起码也搞个像样的ui组件出来,这样才算是学会了。

  今天爬香山回来,累的够呛,时辰不早,收工睡觉~

分享到:
评论

相关推荐

    AngularJS 自定义指令 - ECharts 2 雷达图

    在本文中,我们将深入探讨如何在AngularJS框架中创建自定义指令来封装ECharts 2的雷达图。ECharts是一款由百度开发的开源JavaScript图表库,它提供了丰富的可视化图表类型,包括雷达图。AngularJS是一个强大的前端...

    AngularJS 自定义指令 - ECharts 2 柱状图

    在本文中,我们将深入探讨如何在 AngularJS 中创建自定义指令来封装 ECharts 2 的柱状图。ECharts 是一个基于 JavaScript 的数据可视化库,它提供了丰富的图表类型,包括柱状图、折线图、饼图等。AngularJS 是一个...

    AngularJS 自定义指令 - ECharts 2 折线图

    总结来说,这个案例展示了AngularJS自定义指令如何与第三方库(如ECharts)结合,以提高代码的可复用性和可维护性。在实际开发中,可以根据需求进一步扩展这个指令,例如增加更多配置选项、支持动态加载数据等功能。

    AngularJS创建自定义指令的方法详解

    自定义指令是AngularJS中非常强大和灵活的一个特性,它允许开发者封装和复用界面行为。接下来,我们将详细解释自定义指令的原理、实现步骤、实现方法以及相关的注意事项。 ### 指令的原理 在AngularJS中,指令本质...

    前端项目-angularjs-dropdown-multiselect.zip

    本篇文章将深入探讨一个基于AngularJS的前端项目——"angularjs-dropdown-multiselect",它提供了一个功能完善的下拉多选框指令,适用于构建高效、灵活的用户界面。 "angularjs-dropdown-multiselect"是一个专门...

    AngularJs-UI, AngularJs Pagination Angularjs分页 -- Want to be the best pagination..zip

    AngularJs-UI, AngularJs Pagination Angularjs分页 -- Want to be the best pagination.

    前端项目-angularjs-ie8-build.zip

    总的来说,`angular.js-ie8-builds-master`这个项目旨在提供一个能够顺利在IE8上运行的AngularJS 1.3前端应用。通过使用polyfills、特定的修复和优化,我们可以克服IE8的限制,使得现代前端框架也能在老化的浏览器上...

    AngularJS--angular-phonecat

    "AngularJS--angular-phonecat"是一个经典的入门教程,旨在帮助初学者理解AngularJS的核心概念和工作原理。尽管描述中提到这个项目可能与网上的教程存在一些小差异且没有包含测试部分,但它仍然是学习AngularJS的一...

    前端项目-angularjs-color-picker.zip

    "前端项目-angularjs-color-picker" 是一个专门为 AngularJS 框架设计的颜色选择器指令,它允许开发者在 AngularJS 应用中集成色彩选择功能,提供用户友好的交互体验。 **AngularJS 简介** AngularJS 是一个由 ...

    前端项目-angularjs-nvd3-directives.zip

    在本文中,我们将深入探讨基于AngularJS的前端项目——AngularJS-nvd3-directives,以及如何利用这个库来创建交互式的数据可视化应用。NVD3是一个JavaScript库,它基于D3(Data-Driven Documents)库,专为创建可...

    AngularJS模块化开发--增删改查

    4. `directives.js`:可能包含自定义指令,用于扩展AngularJS的功能,例如验证输入或创建复杂的UI组件。 5. `templates` 文件夹:存放各个视图的HTML模板,与ngRoute配置中的路由对应。 6. `styles.css` 或 `...

    前端项目-myforce-angularjs-dropdown-multiselect.zip

    在"myforce-angularjs-dropdown-multiselect"项目中,"dropdown-multiselect"是一个自定义AngularJS指令。指令是AngularJS中的一个强大工具,允许我们扩展HTML的语义,创建可重用的UI组件。在这个特定的指令中,它...

    angularjs-chapter1-示例.rar

    本教程将通过"angularjs-chapter1-示例.rar"中的实践案例,深入浅出地讲解AngularJS的基本概念和核心特性,帮助初学者快速上手。 1. **AngularJS简介** AngularJS是MVC(Model-View-Controller)架构的实现,它...

    angularjs-chapter3-示例.rar

    angularjs-chapter3-示例.rar

    angularjs指令 下拉框

    "angularjs指令 下拉框"这个主题聚焦于如何利用AngularJS创建一个自定义的下拉框(Dropdown)指令。下拉框在Web开发中非常常见,常用于选项选择或者导航菜单。 首先,我们需要理解AngularJS中的指令是如何工作的。...

    angularjs过滤器--filter与ng-repeat配合有奇效

    在介绍AngularJS过滤器-filter与ng-repeat的配合使用时,我们首先需要了解这两个指令在AngularJS框架中所扮演的角色。AngularJS是一个开源的前端框架,由Google支持,广泛用于开发动态Web应用程序。它通过引入双向...

    angularjs-chapter4-示例.rar

    本篇将详细解析"angularjs-chapter4-示例.rar"中所涵盖的第四章核心概念及实战应用。 在AngularJS的第四章中,主要探讨了以下几个关键知识点: 1. **双向数据绑定**:AngularJS的核心特性之一,它实现了视图与模型...

    AngularJS的启动过程---加上了指令执行机制框图.pdf

    - AngularJS会从DOM树的根节点开始寻找`ng-app`指令,该指令指示AngularJS从何处开始编译和启动应用程序。如果没有找到`ng-app`指令,那么需要手动调用`angular.bootstrap`来启动应用。 3. **调用bootstrap方法**...

    angularjs自定义指令directive正则表达校验

    在AngularJS中,自定义指令通过`@Directive`装饰器声明,其基本结构包括: ```javascript app.directive('directiveName', function() { return { restrict: 'AECM', // A - attribute, E - element, C - class, ...

    AngularJS ng-value 指令-AngularJS 实例.zip

    ng-value指令的语法是在HTML元素上添加`ng-value`属性,并将AngularJS表达式作为其值。例如: ```html &lt;input type="text" ng-value="myModel"&gt; ``` 这里,`myModel`是AngularJS中的一个模型变量,它的值会被...

Global site tag (gtag.js) - Google Analytics