angularJs中自定义directive的数据交互
首先放官方文档地址: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的数据交互的更多相关文章
- AngularJS中自定义有关一个表格的Directive
本篇体验在AngularJS中自定义一个有关表格的Directive.表格的需求包括: ● 表格结构 <table> <thead> <tr> ...
- angularjs中的directive scope配置
angularjs中的directive scope配置 定义directive其中重要的一环就是定义scope,scope有三种形式: 默认的scope,DOM元素上原有的scope scope: ...
- AngularJS中有关Directive的汇总
本篇通过几个例子对AngularJS中的Directive进行汇总. 例子1,单向绑定和双向绑定 <html ng-app="myApp"> <head> ...
- AngularJS中使用Directive、Controller、Service
AngularJS是一款非常强大的前端MVC框架.同时,它也引入了相当多的概念,这些概念我们可能不是太熟悉. (1)Directive 指令 (2)Controller 控制器 (3)Service ...
- Vue中独立组件之间数据交互
独立组件之间数据交互:通过自定义事件 组件A中的[数据],传递给组件B 1.创建组件A,组件B 2.组件B在实例创建完成时就开始监听事件[等待接收数据]:钩子 3.组件A中触发事件,发送数据 注意:接 ...
- 关于angularjs 中自定义过滤器
包子认为,在angularjs中,经常需要用到自定义过滤器,来过滤相应的功能,自定义过滤器非常的简单,我就直接贴代码啦 其中input就是你需要进行操作的对象,,,用法就直接就是 是不是很easy.. ...
- angularjs中的directive
正在初学angularjs中,在网上看到一篇详细讲解directive指令的文章,于是就记录在这里和大家一起分享 angular.module('docsTransclusionExample', [ ...
- AngularJS中自定义过滤器
AngularJS中为我们提供了一些内置的过滤器,这里列举一些自定义过滤器的场景. 自定义过滤器,不带参赛 //过滤 不带参赛 app.filter('ordinal', function () { ...
- angularJS中自定义指令
学习了angularJS一周,但是大部分时间被自定义指令占用了.博主表示自学互联网好心塞的,发现问题的视觉很狭窄,这比解决问题要更难.这篇文章首先介绍了自定义,然后介绍了在使用自定义指令遇到的问题. ...
随机推荐
- ACM-光滑最小生成树project——hdu1863
***************************************转载请注明出处:http://blog.csdn.net/lttree************************** ...
- Ubuntu Ruby On Rails安装和配置
在这篇文章中ubuntu通过rvm安装ruby和rails.步借鉴了官方网站和网上信息,这里给大家分享. 1. 安装mapapis公钥: gpg --keyserver hkp://keys.gnup ...
- datagridcolumn单元格怎么显示查询到的某个表的字段值(字段值可能为多个)
例如,在之前做的项目中,查询mhz_xckcr表,select出某个业务的现场勘察人信息,select出的现场勘察人姓名(可能有多个)要在前台datagrid的一个datagridcolmn单元格显示 ...
- 如果你使用上述这段12行的JavaScript代码,就可以能让firefox、chrome、safari浏览器崩溃,而且还能让iphone重启,安卓手机闪退!
<html> <body> <script> var total=""; for (var i=0;i<1000000;i ) { tot ...
- ADS-B显示终端5.9
更改日志 1 更新背景地图.增加了全国范围内的VOR电台.DME.NDB导航台信息,包含有坐标信息.代码信息.频率等内容. VOR电台.DME.NDB导航台信息来自中国民航局公布的航行情况资料汇 ...
- Android 实现用户列表信息的功能,然后选择删除幻灯片删除功能
在项目开发过程中.经常须要对用户列表的信息进行删除的操作.Android中经常使用的删除操作方式有两种 .一种就是类似微信的滑动出现删除button方式,另一种是通过CheckBox进行选择.然后通过 ...
- C++中的静态多态和动态多态
C++中的静态多态和动态多态 今天的C++已经是个多重泛型编程语言(multiparadigm programming lauguage),一个同时支持过程形式(procedural).面向对象形式( ...
- ASP.NET Web Api构建基于REST风格的服务实战系列教程
使用ASP.NET Web Api构建基于REST风格的服务实战系列教程[十]——使用CacheCow和ETag缓存资源 系列导航地址http://www.cnblogs.com/fzrain/p/3 ...
- CPU 硬盘性能
CPU 硬盘性能到底相差多少 本文以一个现代的.实际的个人电脑为对象,分析其中CPU(Intel Core 2 Duo 3.0GHz)以及各类子系统的运行速度——延迟和数据吞吐量.通过粗略的估算PC各 ...
- SharePoint SPHierarchyDataSourceControl+SPTreeView
今天使用SPHierarchyDataSourceControl和SPTreeView来显示SharePoint文档库层级结构的过程中,发现一直在报下面的错误: The target 'ctl00$c ...