AngularJS初识--指令相关知识总结

指令本质上就是AngularJS扩展具有自定义功能的HTML元素的途径。

指令的创建

指令的创建方法有四种格式

  • 以元素的形式创建:<my-directive></mydirective>
  • 以属性形式创建: <div my-directive></div>
  • 以类的形式创建: <div class='my-dirctive'></div>
  • 以注释的形式创建: <!-- directive:mydirective-->

考虑浏览器的兼容性 我们通常使用属性的形式创建指令

<div my-directive my-url="www.google.com" my-link-text="click me">  
</div>

通过AngularJS模块API中的.directive()方法,我们可以通过传入一个字符串和一个函数注册一个新指令。其中字符串是这个指令的名字,指令名应该是驼峰命名风格的,函数应该返回一个对象

angular.module('myapp',[]);
app.directive('myDirective',function(){
        return {
            restrict:'EA',
            template:'<a href="www.google.com">click</a>',  
        }
    })

运行程序,在审查元素中查看元素

这里写图片描述
可以看到div元素中生成了一个a标签。
return中含有restrict设置。这个设置告诉Angular在编译HTML时用哪种声明格式来匹配指令定义 我们可以指定一个或多个格式
可以指定的格式为:元素(E)、属性(A)、类(C)或注释(M) 的格式

如果想将自定义标签从生成的DOM中完全移除掉,并只留下模板生成的链接。需要在return中添加一个新的设置replace属性

replace:true

再次看一下生成后的代码,我们发现DOM中的原始的指令声明已经不见了,只有模板中生成HTML
这里写图片描述

replace方法会用自定义元素取代指令声明,而不是嵌套在其内部

指令的常用配置

replace: 是一个布尔值,如果设置了该参数,值必须为true,因为默认值为false。默认值意味着模板会被当做子元素插入到调用此指令的元素内部
template: 必须被设置为一段HTML文本或者一个可以接受两个参数的函数,参数为tElement和tAttrs,并返回一个代表模板的字符串
templateUrl: 可以是一个代表外部HTML文件路径的字符串或者一个可以接收两个参数的函数,参数为tElement和tAttrs,并返回一个外部HTML文件路径的字符串。
scope: 隔离作用域,具体见下文
transclude:可选参数 如果设置了,其值必须为true,它的默认值为false,嵌入通常用来创建可复用的组件,典型的例子是模态对话框或导航栏
controller:该参数可以是一个字符串或者一个函数,当设置为字符串时,会以字符串的值为名字,来查找注册在应用中的控制器的构造函数,参数也可以用一个匿名构造函数的方式来定义一个内联的控制器(由于指令可以require其他指令所使用的控制器,因此控制器常用来被放置在多个指令间共享的动作)。
controllerAs: 该参数被用来设置控制器的别名,可以以此为名来发布控制器,并且作用域可以访问controllerAS。
require:参数为字符串或数组,字符串代表另外一个指令的名字。require会将控制器注入到其值所指定的指令中,并作为当前指令的连接函数的第四个参数。字符串或数组元素的值是会在当前指令的作用域中使用的指令名称。使用require可以实现指令间的通信。
require的参数值可以使用下面的前缀进行修饰,这会改变查找控制器时的行为

  • ? 如果在当前指令中没有找到所需要的控制器,会将null作为川味林肯函数的第四个参数
  • ^ 如果添加了^前缀,指令会在上游的指令链中查找require参数所指定的控制器
  • ?^ 将前面两个选项的行为组合起来,我们可选择地加载需要的指令并在父指令链中进行查找

如果没有前缀,指令将在自身所提供的控制器宏进行查找,如果没有找到任何控制器,就抛出错误。
compile:该选项返回一个对象或者函数。通常情况下,如果设置了compile函数,说明我们希望在指令和实时数据被放到DOM中之前进行DOM操作,在这个函数中进行诸如添加和删除节点等DOM操作是安全的。编译函数负责对模板DOM进行转换
link:该选项返回一个函数,用该函数可以操作DOM的指令,负责设置事件爱你监听器,监视数据变化和实时的操作DOM。如果指令中定义有require选项,函数签名中会有第四个参数,代表控制器或所依赖的指令的控制器
compile和link选项是互斥的。如果同时设置了这两个选项,那么compile所返回的函数当做连接函数,而link选项本身则会被忽略

controller与controllerAS的区别:controller as是将属性和方法直接绑定到controller上;controller将属性和方法绑定到作用域上
使用controller as的优点是可以使用js的原型类编写controller

指令的通信

指令可以和指令所在的控制器进行通信。当同一指令需要执行不同的方法时,可以为两个相同的指令添加不同的属性值实现。具体做法如下
先创建两个hello指令

<div ng-controller='myCtrl'>
    <hello emitAttr='loadOne()'>滑动触发事件</hello>
    <hello emitAttr='loadTwo()'>滑动触发事件</hello>

</div>

在script标签中添加代码如下

var app = angular.module('myapp',[]);
app.controller('myCtrl',function($scope){
    $scope.loadOne = function(){
        console.log('load one');
    }
    $scope.loadTwo = function(){
        console.log('load Two');
    }
})
// 当同一指令中需要执行不同的方法时 使用指令中的属性
app.directive('hello',function(){
    return{
        transclude:true,
        template:'<div ng-transclude></div>',
        link:function(scope,ele,attr){
                ele.bind('mouseenter',function(){
                    scope.$apply(attr.emitattr);
                })              
            }
        }
    })

另外,指令间通信需要借助require属性设置所依赖的控制器,并在link中引入指令。

<div>
<div>
    <superman strength> 动感超人一</supuerman>
</div>
<div>
    <superman strength> 动感超人一</supuerman>
</div>
<div>
    <superman strength> 动感超人一</supuerman>
</div>
</div>
<script type="text/javascript">
    var app = angular.module('myapp',[]);
    app.controller('myCtrl',function($scope){
        $scope.loadOne = function(){
            console.log('load one');
        }
        $scope.loadTwo = function(){
            console.log('load Two');
        }
    })
    // 当同一指令中需要执行不同的方法时 使用指令中的属性
    app.directive('hello',function(){
        return{
            transclude:true,
            template:'<div ng-transclude></div>',
            link:function(scope,ele,attr){
                ele.bind('mouseenter',function(){
                    scope.$apply(attr.emitattr);
                })              
            }
        }
    })

关于完整代码,请参见我的github 指令与控制器 指令与指令

隔离作用域

在指令函数中,可以使用scope为指令划分作用域。scope的作用数描述指令与父作用域的关系,可能的取值有:

  • false:默认值 使用父作用域作为自己的作用域
  • true:新建一个作用域,该作用域继承父作用域
  • javascript对象:与父作用域隔离 并制定可以从父作用域访问的变量

这里主要说一下第三种取值,当scope是一个对象时,就意味着指令有了一个属于自己的scope 对象,这个对象只能在指令的方法中或指令的模板字符串中使用。通过搭建桥梁 可以访问父作用域的部分参数
scope对象中含有若干对键值对,其中key为指令自己的模板(template)中要使用的一个名称, value为绑定策略是使用用符号前缀来说明如何为指令传值。
绑定策略的取值规则如下:

  • @ :传递一个字符串作为属性的值 str: ‘@string’
  • = : 使用父作用域中的一个绑定数据到指定的属性中 name:’=username’
  • & :使用父作用域中的一个函数 可以在指令中调用 getName: ‘&getUserName’

    <div ng-controller = 'insulate'>
        <span say-hello speak='content'>hello</span>
    </div>
    

在script标签中添加控制器和指令函数

app.controller('insulate',function($scope){
        $scope.content = 'today is wednesday';
    })
    app.directive('sayHello',function(){
        return{
            restrict:'EA',
            template:'<div>hello {{cont}}</div>',
            replace:true,
            scope:{
                cont:'=speak',
            }
        }
    })
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值