专栏首页菜鸟计划angularjs 指令详解

angularjs 指令详解

一、指令定义

对于指令,可以把它简单的理解成在特定DOM元素上运行的函数,指令可以扩展这个元素的功能。

首先来看个完整的参数示例再来详细的介绍各个参数的作用及用法:

<div my-directive></div> 

二、指令参数的作用和意义(这个地方只选常用的几种来讲一下)

restrict[string]

restrict是一个可选的参数。用于指定该指令在DOM中以何种形式被声明。默认值是A,即以属性的形式来进行声明。
可选值如下:
E(元素)

<my-directive></my-directive> 
A(属性,默认值)

<div my-directive></div> 
C(类名)

<div class="my-directive:expression;"></div> 
M(注释)

<--directive:my-directive expression-->

一般考虑到浏览器的兼容性,强烈建议使用默认的属性就可以即即以属性的形式来进行声明。最后一种方式建议在不要求逼格指数的时候千万不要用。

replace[bool]

replace是一个可选参数,如果设置了这个参数,值必须为true,因为默认值为false。默认值意味着模板会被当作子元素插入到调用此指令的元素内部, 例如上面的示例默认值情况下,生成的html代码如下:

<my-directive value="http://www.baidu.com" text="百度"><a href="http://www.baidu.com">百度</a></my-directive>

如果设置replace=true

<a href="http://www.baidu.com" value="http://www.baidu.com" text="百度">百度</a>

templateUrl[string or function]

templateUrl是可选的参数,可以是以下类型:

  • 一个代表外部HTML文件路径的字符串;
  • 一个可以接受两个参数的函数,参数为tElement和tAttrs,并返回一个外部HTML文件路径的字符串。

无论哪种方式,模板的URL都将通过ng内置的安全层,特别是$getTrustedResourceUrl,这样可以保护模板不会被不信任的源加载。 默认情况下,调用指令时会在后台通过Ajax来请求HTML模板文件。加载大量的模板将严重拖慢一个客户端应用的速度。为了避免延迟,可以在部署应用之前对HTML模板进行缓存。

    angular.module('app',[])
    .directive('myDirective', function () {
            return { 
                restrict: 'A', 
                templateUrl: function (elem, attr) {
                    return attr.value + ".html";  //当然这里我们可以直接指定路径,同时在模板中可以包含表达式
                }
        };
    })

 controller[string or function]

 controller参数可以是一个字符串或一个函数。当设置为字符串时,会以字符串的值为名字,来查找注册在应用中的控制器的构造函数.

angular.module('myApp', []) 
.directive('myDirective', function() { 
restrict: 'A',  
replace: true,
templateUrl: 'test.html',
controller: 'SomeController' 
}) 

 可以在指令内部通过匿名构造函数的方式来定义一个内联的控制器

angular.module('myApp',[]) 
.directive('myDirective', function() { 
restrict: 'A', 
controller: 
function($scope, $element, $attrs, $transclude) { 
// 控制器逻辑放在这里
} 
});

我们可以将任意可以被注入的ng服务注入到控制器中,便可以在指令中使用它了。控制器中也有一些特殊的服务可以被注入到指令当中。这些服务有:

1. $scope

与指令元素相关联的当前作用域。 2. $element 当前指令对应的元素。 3. $attrs 由当前元素的属性组成的对象。

<div id="aDiv"class="box"></div>
具有如下的属性对象:
{ 
id: "aDiv", 
class: "box" 
}

三、指令作用域

scope参数[bool or object]

scope参数是可选的,可以被设置为true或一个对象。默认值是false。

html代码

 <div ng-controller='MainController' ng-init="myProperty='Hello World!'">
        外部: {{ myProperty}}
        <input ng-model="myProperty" />
        <div my-directive></div>
    </div>

js代码

    angular.module('myApp', [])
        .controller('MainController', function ($scope) {
        })
        .directive('myDirective', function () {
            return {
                restrict: 'A',
                scope:false,//切换为{},true测试
                priority: 100,
                template: '<div>内部:{{ myProperty }}<input ng-model="myProperty"/></div>'
            };
        });

 当我们改变scope的值我们会发现

false:继承但不隔离

1.当我们将scope设置为false的时候,我们创建的指令和父作用域(其实是同一个作用域)共享同一个model模型,所以在指令中修改模型数据,它会反映到父作用域的模型中。

true:继承并隔离

2.当我们将scope设置为true的时候,我们就新创建了一个作用域,只不过这个作用域是继承了我们的父作用域;

我觉得可以这样理解,我们新创建的作用域是一个新的作用域,只不过在初始化的时候,用了父作用域的属性和方法去填充我们这个新的作用域。它和父作用域不是同一个作用域。

{}:隔离且不继承 

3.当我们将scope设置为{}时,意味着我们创建的一个新的与父作用域隔离的新的作用域,这使我们在不知道外部环境的情况下,就可以正常工作,不依赖外部环境。

四、绑定策略

 在使用独立作用域scope的时候,一般有三种绑定传递策略, @单向传递字符串  =双向传递  &单向传递父级的方法

<inputtype="text"ng-model="myUrl">
<div my-directive my-url="{{myUrl}}" my-age="age" change-my-age="changeAge()></div> ①
angular.module('myApp',[])
.directive('myDirective',function(){
return{
restrict:'A',//属性方式
replace:true,
scope:{
myUrl:'@',//@绑定策略(默认绑定到 my-url指令属性)
myAge:'='//=双向绑定(父子互相影响)
changeMyAge:'&' //传递父作用域的方法
},
template:'<a href="{{myUrl}}" ng-click=changeMyAge()>{{ myAge }}</a>'
}
});
  • 在上面的代码中,我创建了一个指令myDirective 该指令创建了两个变量 myUrl、myLinkText,并且这俩个变量都是采用@绑定策略
  • 说一下,不管是@=还是&绑定策略,它们都有一个默认的方式,以@绑定策略为例,如上面代码那么样:myUrl:'@',直接用一个@表示绑定的方式,它就会默认得将指令属性my-url的值赋值给myUrl变量。
  • 当然,你不想使用默认的方式,也就是说,你不想myUrl变量绑定my-url的值,而想要绑定其它属性名的值,那么你可以在@后加上你希望的属性名(格式要求:驼峰式)。
  • 如,我想讲myUrl绑定到<myDirective></myDirective>指令的some-attr属性的值,那么你可以这样写:myUrl:'@someAttr'
  • 那么我们知道了指令的myUrl变量的值是如何来的,那么我们要如何在template中使用它呢?
  • 这个很简单,看上面的代码就能很明白了,我们在template中的代码中需要用表达式的方式对其引用{{myUrl}},这样我们就能够使用到myUrl变量的值了~

  1. 本地作用域属性:使用@符号将本地作用域同DOM属性的值进行绑定,使指令内部作用域可以使用外部作用域的变量: 

可以在指令中使用绑定的字符串了。

  2.  双向绑定:通过=可以将本地作用域上的属性同父级作用域上的属性进行双向的数据绑定。就像普通的数据绑定一样,本地属性会反映出父数据模型中所发生的改变。 

  3. 父级作用域绑定 通过&符号可以对父级作用域进行绑定,以便在其中运行函数。意味着对这个值进行设置时会生成一个指向父级作用域的包装函数。    要使调用带有一个参数的父方法,我们需要传递一个对象,这个对象的键是参数的名称,值是要传递给参数的内容。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • vue组件详解(四)——使用slot分发内容

    一、什么是slot 在使用组件时,我们常常要像这样组合它们: <app> <app-header></app-header> <app-footer><...

    柴小智
  • vue内置指令详解——小白速会

    指令 (Directives) 是带有 v- 前缀的特殊属性,职责是,当表达式的值改变时,将其产生的连带影响,响应式地作用于 DOM。 内置指令 1、v-bin...

    柴小智
  • JSX渲染原理

    1.基于babel-preset-react-app这个语法解析包,把jsx语法转换成一个名为 React.createElement() 的方法调用。

    柴小智
  • 记一次问题分析解决的完整过程

    比如龙叔的饭否,2016 年就被曝光了,我是前几天才知道,赶紧跑去围观了一把,满足下自己作为中年油腻大叔的好奇心。

    sylan215
  • react ---- Router路由的使用和页面跳转

    http://react-guide.github.io/react-router-cn/docs/Introduction.html

    小蔚
  • 通过7个python函数理解区块链 原

    我想对于那里的很多人来说,区块链就是这种现象,很难不让你头脑发热。我开始观看视频和阅读文章,但对我个人而言,直到我编写自己的简单区块链,我才真正理解它是什么以及...

    笔阁
  • 通过7个函数解密区块链(附代码)

    我想对很多人来说,区块链是一种很难理解的技术,虽然我也看了很多视频和文章,但从我个人角度来讲,直到我开始写一些简单的区块链应用,我才真正理解了它是什么以及它的潜...

    数据派THU
  • Human Interface Guidelines — Navigation

    霖酱
  • 模仿百度新闻列表底部的“加载更多”

    前言   自从上个月来到了学校的信息化中心实习后自由安排的时间越来越少,遂好久没来更新博客了。   昨天在完成一个模仿手机端百度新闻列表底“点击加载更多”的功能...

    逸鹏
  • @@IDENTITY与SCOPE_IDENTITY() 及IDENT_CURRENT 的区别

    本文转载:http://www.cnblogs.com/lovemyth/archive/2007/03/14/674584.html

    跟着阿笨一起玩NET

扫码关注云+社区

领取腾讯云代金券