angularjs->directive(指令)

来源:互联网 发布:java byte二维数组 编辑:程序博客网 时间:2024/06/09 21:04

指令的基础认识

angularjs指令:解决html标签复用
angularjs指令可以指定一个标签,让后用template去替换指定标签的内容

下面是一个小案例,对指令结构的基本解释

html结构:

    <div ng-app="s9.app">        <!--指令的 标签名用法,指令名用作了标签名-->        <s9-header></s9-header>        <!--指令的 属性名的方法,指令名用作了属性名-->        <div s9-header></div>    </div>

js代码:

var app = angular.module("s9.app",[]);app.directive("s9Header",function(){    var directiveObj = {        template:'<div class="page-header">'                + '<h1>流行框架阶段 <small>AngularJs指令</small></h1>'                + '</div>'                  };           return directiveObj;});

解析:
app.directive()用来定义一个指令,
第一个参数:指令名字,同时也会被: 用作html上的属性名或是标签名
所以:必须使用驼峰语法,到页面上就会自动转为横线连接(s9-header)
第二个参数:指令的工厂函数
返回一个对象(directiveObj),这个对象描述了我们的指令如何被angularjs解析

directiveObj:

用于描述这个指令的对象,这个对象中的各种字段,都是angularjs规定的

template:

指令的模板,当使用这个指令时,模板的内容替换对应标签的标签体
(使用的结果:用标签或者属性名方法,放到html上,指定某个标签)

replace

replace设置为true:完全替换了自定义标签,自定义标签就不存在了
标签名用法、属性名用法的自定义标签都不存在了
**如果用的是属性名方法自定义标签,那么指令名字的属性会保留在指令指定的标签中(s9-header)

使用replace有一个小问题!!!
template模板中的标签不能是并行的,也就是必须要有一个根元素
原因:
replace为true时,会把自定义标签替换,指令的作用域就作用在模板指定的标签上;
一个指令(directive)要绑定在两个并行的标签上,指令就不知道到底要绑定到哪个标签上,就会报错

html结构:

<div ng-app="s9.app">        <!--指令的 标签名用法,指令名用作了标签名-->        <s9-header></s9-header>        <!--指令的 属性名的方法,指令名用作了属性名-->        <!--此时查看html代码,会发现s9-header这个属性会保留在指令指定的标签中-->        <div s9-header></div></div>

js代码:

var app = angular.module("s9.app",[]);app.directive("s9Header",function(){    var directiveObj = {        template:'<div class="page-header">'        + '<h1>流行框架阶段 <small>AngularJs指令</small></h1>'        + '</div>',        // replace用法        replace: true    };    return directiveObj;});

transclude

允许在指令的template里面指定一个标签(用ng-transclude指令指定),然后把外部的内容嵌入到这个标签中。外部的内容:宿主标签原来的标签体内容

如果自定义标签中有字符串,则会被覆盖

html结构

<div ng-app="s9.app">    <s9-panel>我是宿主标签中的内容</s9-panel></div>

js代码

var app = angular.module("s9.app",[]);app.directive("s9Panel",function(){    var templateSrt =            '<div>'            + '<div ng-transclude>' //加上ng-transclude            + '</div>'            + '</div>';        var directiveObj = {            template: templateSrt,            transclude: true    };    return directiveObj;});

scope

  1. scope字段未设置或设置为false:
    使用指令所指定标签的外部的作用域(没有自己作用域),该指令继承了
    父作用域的一切属性和方法,所以在中的模板中我们可以使用这些属性和方法
    在指令中修改数据时,会反应到父作用域的模型中
    因为他两就是同一个作用域

  2. scope字段或设置为true:
    创建了一个新作用域,这个作用域继承了我们的父作用域,
    此时在input中输入,指令的msg发生了变化,指令外的 msg 没有发生 变化
    可以理解为:新创建的作用域是一个新作用域,只不过在初始化的时候,用了父作用域的属性和方法去填充这个新作用域,它和作用域不是同一个作用域

html结构

<div ng-controller="MainController">    <div>控制器:{{msg}}</div>    <!--继承的是MainController作用域-->    <s9-panel></s9-panel></div>

js代码:

var app = angular.module("s9.app",[]);app.run(function($rootScope){    $rootScope.msg = "hello run";});app.controller("MainController",function($scope){    $scope.msg = "hello controller";})app.directive("s9Panel",function(){    var templateSrt = "<div><input type='text' ng-model='msg'></div>";    var directiveObj = {        template: templateSrt,        scope: false        };    return directiveObj;})

scope设置为自定义对象时

scope设置为自定义对象,就代表使用的是孤立作用域(隔离作用域)

html结构:

<div ng-app="s9.app">    <div ng-controller="MyController">        <div>{{msg}}</div>        <div my-music my-word="happy" my-col="msg+'...'" my-ipt='msg'></div>    </div></div>

js代码:

var app = angular.module("s9.app",[]);app.controller("MyController",function($scope){    $scope.msg = "hello";})app.directive("myMusic",function(){    var templateStr = "<span>{{myWord}}</span>";    var obj = {        template: templateStr,        scope: {            myWord:"@",            // 如果属性值中有插值语法,先运算插值语法的值            // 再把字符串传递过来            myCol:"<",            // 和外部作用域指定的字段的数据 做了一个双向的数据绑定            myIpt:"="        },        // 因为是孤立作用域,所以访问不到父元素作用域中的msg        // 结果就是undefined        controller:function ($scope) {            console.log($scope.msg);        }    };    return obj;})

代码解析:

  1. ‘@’ 作用(传纯字符串):
    可以将宿主标签上的属性值绑定到template指定的标签上的字段
    myWord 是指令作用域上的字段
    这个字段上的数据来自于指令所标记的标签(属性名方法的自定义标签)
    上的 my-word属性
    前提就是:指令作用域上的字段名 = 自定义标签上的属性名
  2. ‘< ’ 作用:
    绑定原理同@,
    作用是:如果属性值中有插值语法,先运算插值语法的值再把字符串传递过来
  3. ‘=’ 作用:
    绑定原理同@
    作用是:和外部作用域指定的字段的数据 做了一个双向的数据绑定

// link函数参数解析
参数一:指令的作用域
参数二:宿主标签
参数三:宿主标签上的属性
link函数中,参数不受依赖注入的影响,固定顺序固定传参
整个angularjs框架中,link函数常用于操作dom
用的就是elem对象,它是一个JQLite对象,类似以JQuery对象

js代码:

angular.module("s9.app",[])        .directive("myDirective",function(){            var directiveObj = {                template: "<div><input type='text' ng-model='name'></div>",                scope: {                    name: "@"                },                link: function(scope,elem,attrs){                    elem.find("input")[0].focus(); // 让input标签获取焦点                    console.log(attrs['name']); // 结果:tom                }            };            return directiveObj;        })
0 0