就我对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
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
P70系列延期,华为新旗舰将在下月发布
3月20日消息,近期博主@数码闲聊站 透露,原定三月份发布的华为新旗舰P70系列延期发布,预计4月份上市。
而博主@定焦数码 爆料,华为的P70系列在定位上已经超过了Mate60,成为了重要的旗舰系列之一。它肩负着重返影像领域顶尖的使命。那么这次P70会带来哪些令人惊艳的创新呢?
根据目前爆料的消息来看,华为P70系列将推出三个版本,其中P70和P70 Pro采用了三角形的摄像头模组设计,而P70 Art则采用了与上一代P60 Art相似的不规则形状设计。这样的外观是否好看见仁见智,但辨识度绝对拉满。
更新动态
- 黑鸭子2010-再度重相逢[首版][WAV+CUE]
- 【原神手游】5.2版本圣遗物优化详情
- 方季惟.1989-一生只爱一次【蓝与白】【WAV+CUE】
- 群星.1997-强力舞曲总动员【金点】【WAV+CUE】
- 盘尼西林.2024-岛与黎明【智慧大狗】【FLAC分轨】
- 刀郎《柔情经典》 2CD[WAV分轨][3.8G]
- 群星2024《民谣精选》原音母版1:1直刻[低速原抓WAV+CUE][1.1G]
- 经典《泰坦尼克号原声大碟》[WAV+DSF+FLAC多版][5.2G]
- 魔兽世界兽王猎输出宏代码是什么 兽王猎翻页输出宏命令代码分享
- 魔兽世界wlk野德一键输出宏是什么 wlk野德一键输出宏介绍
- wlk鸟德一键输出宏是什么 wlk鸟德一键输出宏介绍
- 《明末:渊虚之羽》外网新宣传:有勇气面对障碍吗?
- 视觉盛宴!V社公布《看火人》团队新作水面物理效果演示
- 张艺谋呼吁观众走进影院看电影:对解说短视频很无语
- 车载音乐最强享受 《车载极致女声精选》[WAV分轨][1G]