<!DOCTYPE html> <html ng-app="myApp"> <head> <meta charset="UTF-8"> <title>Directive指令与Controller控制器交互</title> <!--引入js库anglarjs--> <script type="text/javascript" src="https://www.jb51.net/framework/1.3.0.14/angular.js"></script> <script type="text/javascript" src="https://www.jb51.net/js/Directive&Controller.js"></script> </head> <body> <div ng-controller="myAppCtrl"> <loader hello howToLoad="loadData()">数据加载......</loader> </div> <div ng-controller="myAppCtrl2"> <loader hello howToLoad="loadData2()">数据加载2......</loader> </div> </body> </html>
Directive&Controller.js
var myApp = angular.module('myApp', []); myApp.controller('myAppCtrl', ['$scope', function($scope){ console.log($scope); $scope.loadData = function(){ console.log('数据加载中.....'); } }]); myApp.controller('myAppCtrl2', ['$scope', function($scope){ console.log($scope); $scope.loadData2 = function(){ console.log('数据加载中2.....'); } }]); //指令与控制器之间交互 myApp.directive('loader', function(){ return { restrict: 'EA', template: '<div ng-transclude></div>', transclude: true, replace: true, /*scope: {}, 独立scope*/ link: function(scope, element, attrs){ element.bind('mouseenter', function(){ /*这里调用controller中的方法三种方式*/ /*(1) scope.loadData(); (2) scope.$apply('loadData()'); (3) attrs.howtoload === 属性上绑定的函数名称*/ //属性方式 注意坑!!! howtoload 得小写 scope.$apply(attrs.howtoload); }) } } })
实现的效果是当鼠标滑过div元素时,调用一个加载数据的方法。
上述例子中定义了两个控制器,然后两个控制器中都使用了loader指令,并且,每个指令中都有一个参数 howToLoad .
关于指令中的 link ,上面介绍运行机制中可以了解到,link: function postLink(scope, element, attrs) {...}是用来操作dom和绑定监听事件的。
link中会有三个参数:scope(指令所属的控制器中的 $scope 对象)、element(指令所属dom元素)、attrs(dom元素所传的参数
如howToLoad 参数给的值 loadData()
然后对于如何调用所需函数,有两种方法:
1> scope.loadData() 两个控制器方法不一致时,就不能用了
2> scope.$apply() $apply()方法会从所有控制器中找到多对应的方法。这就实现了指令的复用。
明确对于控制器ng-controller都会创建属于自己独立的scope;对于指令若无scope:{}声明会继承控制器中的scope
七、指令与指令的交互
index.html
<!DOCTYPE html> <html ng-app="myModule"> <head> <meta charset="UTF-8"> <title>directive指令与directive指令之间的交互</title> <!--引入第三方样式库bootstrap.min.css--> <link href="https://www.jb51.net/framework/bootstrap-3.0.0/css/bootstrap.min.css" /> <!--引入js库anglarjs--> <script type="text/javascript" src="https://www.jb51.net/framework/1.3.0.14/angular.js"></script> <script type="text/javascript" src="https://www.jb51.net/js/Directive&Directive.js"></script> </head> <body> <div> <div> <superman strength>动感超人---力量</superman> </div> </div> <div> <div> <superman strength speed>动感超人2---力量+敏捷</superman> </div> </div> <div> <div> <superman strength speed light>动感超人3---力量+敏捷+发光</superman> </div> </div> </body> </html>
Directive&Directive.js
var myModule = angular.module('myModule',[]); //指令与指令之间交互 myModule.directive('superman', function(){ return { scope: {},/*独立作用域*/ restrict: 'AE', template: '<button ng-transclude></button>', transclude: true, controller: function($scope){ /*暴露controller里面方法*/ $scope.abilities = []; this.addStrength = function(){ $scope.abilities.push('strength'); }; this.addSpeed = function(){ $scope.abilities.push('speed'); }; this.addLight = function(){ $scope.abilities.push('light'); }; }, link: function(scope, element, attrs, supermanCtr){ element.addClass = "btn btn-primary"; element.bind('mouseenter', function(){ console.log(scope.abilities); }) } } }) myModule.directive('strength', function(){ return { require: "^superman",/*require参数指明需要依赖的指令*/ link: function(scope, element, attrs, supermanCtr){ supermanCtr.addStrength(); } } }); myModule.directive('speed', function(){ return { require: "^superman", link: function(scope, element, attrs, supermanCtr){ supermanCtr.addSpeed(); } } }); myModule.directive('light', function(){ return { require: "^superman", link: function(scope, element, attrs, supermanCtr){ supermanCtr.addLight(); } } });
*require参数指明需要依赖的指令
*指令中的controller相当于暴露里面方法,便于指令复用
八、scope作用域绑定策略
scope “@” 把当前属性作为字符串传值