首先放官方文档地址:https://docs.angularjs.org/guide/directive

就我对directive的粗浅理解,它一般用于独立Dom元素的封装,应用场合为控件重用和逻辑模块分离。后者我暂时没接触,但数据交互部分却是一样的。所以举几个前者的例子,以备以后忘记。

directive本身的作用域$scope可以选择是否封闭,不封闭则和其controller共用一个作用域$scope。例子如下:

 <body ng-app="myApp" ng-controller="myCtrl">
<test-directive></test-directive>
<script>
angular.module("myApp",[])
.controller("myCtrl",function($scope){
$scope.data = {
name:"白衣如花"
};
})
.directive("testDirective",function(){
return {
restrict:"E",
template:"<h1>{{data.name||'未定义'}}</h1>"
}
});
</script>
</body>

显示结果为:白衣如花,可以知道directive中的data.name就是myCtrl控制器中的$scope.data.name。

那么封闭的directive呢?怎么封闭,封闭效果是什么样的,封闭后怎么数据交互?这些都是我这几天摸索的东西。

 <body ng-app="myApp" ng-controller="myCtrl">
<test-directive></test-directive>
<script>
angular.module("myApp",[])
.controller("myCtrl",function($scope){
$scope.data = {
name:"白衣如花"
};
})
.directive("testDirective",function(){
return {
restrict:"E",
scope: {},
template:"<h1>{{data.name||'未定义'}}</h1>"
}
});
</script>
</body>

结果显示为:未定义。所以在directive定义时,添加属性scope就可以把directive的作用域和父控制器的作用域分离开来。

好,了解了开放和封闭之后,进入主题,如何进行数据交互。个人觉得数据交互分为:父控制器获取directive的变量;directive获取父控制器的变量;父控制器调用directive的函数;directive调用父控制器的函数。

1.父控制器获取directive的变量。比如封装了一个输入框接受用户输入,父控制器点击搜索按钮要获取用户输入:

 <body ng-app="myApp" ng-controller="myCtrl">
<p>名字:{{outerName}}</p>
<test-directive inner-name="outerName"></test-directive>
<script>
angular.module("myApp",[])
.controller("myCtrl",function($scope){
})
.directive("testDirective",function(){
return {
restrict:"E",
scope: {
innerName: "="
},
template:"<input type='text' ng-model='innerName' placeholder='白衣如花'>"
}
});
</script>
</body>

显示结果如下:

分析:从数据流向说起,testDirective中的一个input输入绑定在innerName中,innerName是directive私有作用域拥有的变量,外部控制器不能直接用。通过innerName: "="传递给html中的inner-name属性,

而inner-name属性则绑定在外部控制器的outerName变量中,所以最后显示在最上面的<p>标签内。上述代码等价于如下代码:

<test-directive name="outerName"></test-directive>
scope: {
innerName: "=name"
},

由inerName: "="变成了innerName: "=name",而html属性绑定也由inner-name变成了name。

2.directive获取父控制器的变量。这个应用场合应该挺多的,比如公共的页眉页脚,公共的展示面板等。

这个用上面例子的"="一样可以实现,于是我们知道了"="是双向绑定。但是我们要防止directive内部意外修改数据该怎么办呢?于是单向绑定"@"就出场了。

 <body ng-app="myApp" ng-controller="myCtrl">
<input type='text' ng-model='outerName' placeholder='白衣如花'>
<test-directive inner-name="{{outerName}}"></test-directive>
<script>
angular.module("myApp",[])
.controller("myCtrl",function($scope){
})
.directive("testDirective",function(){
return {
restrict:"E",
scope: {
innerName: "@"
},
template:"<p>名字:{{innerName}}</p>" +
"<button ng-click='innerName=innerName+1'>点击</button>"
}
});
</script>
</body>

值得注意的是:@在html的属性绑定时需要{{}}开标识,而=则不用。我的理解是,对于父控制器而言,@是数据传递,而=是数据绑定,所以有这些区别。directive中加入了一个按钮用于验证修改数据后

父控制器是否发生改变,结果是=有变化,@无变化,很容易得出结论:=是双向绑定,@是单向绑定。

3.directive调用父控制器的函数。应用场合,暂时想不到(汗)。

变量用=和@来传递,函数则用&。例子如下:

 <body ng-app="myApp" ng-controller="myCtrl">
<p>名字:{{outerName}}</p>
<test-directive on-click="click(name)"></test-directive>
<script>
angular.module("myApp",[])
.controller("myCtrl",function($scope){
$scope.click = function (name) {
$scope.outerName = name || "白衣如花";
}
})
.directive("testDirective",function(){
return {
restrict:"E",
scope: {
onClick: "&"
},
template:"<input type='text' ng-model='innerName' placeholder='白衣如花'>" +
"<button ng-click='onClick({name: innerName})'>点击</button>"
}
});
</script>
</body>

数据传递流程和之上的例子差不多,唯一要注意的是参数传递时,{name: innerName}前者是形参,后者是实参。多个参数时,参数顺序不重要,形参一一对应。

4.父控制器调用directive的函数。这个是前段时间遇到的难点,情况较其他复杂一些。应用场合也很普遍,比如初始化,重置等。

 <body ng-app="myApp" ng-controller="myCtrl">
<button ng-click="click()">重置</button>
<test-directive action="action"></test-directive>
<script>
angular.module("myApp",[])
.controller("myCtrl",function($scope){
$scope.action = {};
$scope.click = function () {
$scope.action.reset();
}
})
.directive("testDirective",function(){
return {
restrict:"E",
scope: {
action: "="
},
template:"<input type='text' ng-model='name' placeholder='白衣如花'>",
controller: function ($scope) {
$scope.action.reset = function () {
$scope.name = "白衣如花"
}
}
}
});
</script>
</body>

又一次用到了=,利用了js中函数也是属性的原理。似乎,理解了=的双向绑定,就很容易调用directive内部函数了。但是初始化呢?

首先想到的是类似的=来引用传递:

 <body ng-app="myApp" ng-controller="myCtrl">
<test-directive action="action"></test-directive>
<script>
angular.module("myApp",[])
.controller("myCtrl",function($scope){
$scope.action = {};
$scope.action.init();
})
.directive("testDirective",function(){
return {
restrict:"E",
scope: {
action: "="
},
template:"<input type='text' ng-model='name' placeholder='白衣如花'>",
controller: function ($scope) {
$scope.action.init = function () {
$scope.name = "白衣如花"
}
}
}
});
</script>
</body>

但是运行却发现,错误显示$scope.action.init is not a function,看提示应该是运行到第7行的时候,$scope.action.init函数还未定义。怎么办呢?把directive提到controller之前试试?一样是错误。

嗯,可以不用函数,直接在directive的controller中执行$scope.name = "白衣如花",似乎很完美,但如果是有参数的初始化呢?事实上js分离后,我遇到的问题是根据http请求的返回结果来初始化directive,由于

网络快慢不一定,导致控件初始化时不一定有http请求的返回(没有有效的初始化参数),也不能保证http请求返回后directive已经初始化(不能用=来进行函数调用)。

需求很明了了,如果能监控参数变化,再执行初始化,此时能保证directive已经加载,而且有有效的参数。正好angularjs提供了$watch。代码如下:

 <body ng-app="myApp" ng-controller="myCtrl">
<test-directive action="action"></test-directive>
<script>
angular.module("myApp",[])
.controller("myCtrl",function($scope){
$scope.action = {name: "白衣如花"};
})
.directive("testDirective",function(){
return {
restrict:"E",
scope: {
action: "="
},
template:"<input type='text' ng-model='name' placeholder='白衣如花'>",
link: function (scope, elem, attrs) {
scope.$watch(attrs.action, function (value) {
scope.action.init();
})
},
controller: function ($scope) {
$scope.action.init = function () {
$scope.name = $scope.action.name
}
}
}
});
</script>
</body>

这是我对于directive数据交互的粗浅理解。想要更详细了解,请参看官方文档:https://docs.angularjs.org/guide/directive

angularJs中自定义directive的数据交互的更多相关文章

  1. AngularJS中自定义有关一个表格的Directive

    本篇体验在AngularJS中自定义一个有关表格的Directive.表格的需求包括: ● 表格结构 <table>    <thead>        <tr>  ...

  2. angularjs中的directive scope配置

    angularjs中的directive scope配置 定义directive其中重要的一环就是定义scope,scope有三种形式: 默认的scope,DOM元素上原有的scope scope: ...

  3. AngularJS中有关Directive的汇总

    本篇通过几个例子对AngularJS中的Directive进行汇总. 例子1,单向绑定和双向绑定 <html ng-app="myApp"> <head> ...

  4. AngularJS中使用Directive、Controller、Service

    AngularJS是一款非常强大的前端MVC框架.同时,它也引入了相当多的概念,这些概念我们可能不是太熟悉. (1)Directive 指令 (2)Controller 控制器 (3)Service ...

  5. Vue中独立组件之间数据交互

    独立组件之间数据交互:通过自定义事件 组件A中的[数据],传递给组件B 1.创建组件A,组件B 2.组件B在实例创建完成时就开始监听事件[等待接收数据]:钩子 3.组件A中触发事件,发送数据 注意:接 ...

  6. 关于angularjs 中自定义过滤器

    包子认为,在angularjs中,经常需要用到自定义过滤器,来过滤相应的功能,自定义过滤器非常的简单,我就直接贴代码啦 其中input就是你需要进行操作的对象,,,用法就直接就是 是不是很easy.. ...

  7. angularjs中的directive

    正在初学angularjs中,在网上看到一篇详细讲解directive指令的文章,于是就记录在这里和大家一起分享 angular.module('docsTransclusionExample', [ ...

  8. AngularJS中自定义过滤器

    AngularJS中为我们提供了一些内置的过滤器,这里列举一些自定义过滤器的场景. 自定义过滤器,不带参赛 //过滤 不带参赛 app.filter('ordinal', function () { ...

  9. angularJS中自定义指令

    学习了angularJS一周,但是大部分时间被自定义指令占用了.博主表示自学互联网好心塞的,发现问题的视觉很狭窄,这比解决问题要更难.这篇文章首先介绍了自定义,然后介绍了在使用自定义指令遇到的问题. ...

随机推荐

  1. 【剑指offer】Q32:从1至n整1出现的次数(python)

    def q32(n, len): if n < 0: return 0 elif n <= 1: return n total = 0 while n > 0: if n >= ...

  2. 表单验证的3个函数ISSET()、empty()、is_numeric()的使用方法

    原文:表单验证的3个函数ISSET().empty().is_numeric()的使用方法 本文就简单讲一下php中表单验证的三个函数,应该比较常用吧,最后给一些示例,请看下文. ISSET();—— ...

  3. SqlServer-COMPUTE BY

    原文:SqlServer-COMPUTE BY COMPUTE BY子句可以通过同一个select语句即查看明细行,又查看汇总行.可以计算子组的汇总值,也可以计算整个结果集的汇总值 COMPUTE 子 ...

  4. 常用Jquery插件整理大全

    做项目的时候总是少不了要用到Jquery插件,但是Jquery插件有太多,每次都要花费一些时间,因此本人就抽时间整理了一些Jquery插件,每个插件都有Demo或者是使用文档供大家下载.整理了一晚上才 ...

  5. Asp.Net Web Api 接口,拥抱支持跨域访问。

    如何让你的 Asp.Net Web Api 接口,拥抱支持跨域访问. 由于 web api 项目通常是被做成了一个独立站点,来提供数据,在做web api 项目的时候,不免前端会遇到跨域访问接口的问题 ...

  6. Javascript多线程引擎(五)

    Javascript多线程引擎(五)之异常处理 C语言没有提供一个像Java一样的异常处理机制, 这就带来了一个问题, 对于一个子函数中发生异常后, 需要在父函数调用子函数的位置进行Check, 如果 ...

  7. 分布式文件系统之MogileFS工作原理及实现过程

    MogileFS是一套高效的文件自动备份组件,由Six Apart开发,广泛应用在包括LiveJournal等web2.0站点上.MogileFS由3个部分组成:   第1个部分:是server端,包 ...

  8. 依赖注入和IOC

    http://www.bbsmvc.com/archiver/csharp/thread-831-1.html 本来想使用一下Ninject的,然后搜索了很久,都没找到比较详细的关于Ninject的使 ...

  9. IP 首部检验和算法

    原创博文,转载请注明出处. 在学习TCP/IP 详解的过程中遇到了不止一次的关于检验和的概念,在吸取了他人理解的前提下,我决定用Wireshark 进行抓包分析. 首先我们得知道IP数据包格式 首先把 ...

  10. 线程:ThreadLocal实现线程范围内共享变量

    在web应用中,一个请求(带有请求参数)就是一个线程,那么如何区分哪些参数属于哪个线程呢?比如struts中,A用户登录,B用户也登录,那么在Action中怎么区分哪个是A用户的数据,哪个是B用户的数 ...