Angular之指令Directive系列

项目筹备近期开启Angular学习,指令比较难理解所以记录备案,推荐视频大漠穷秋 Angular实战 由于篇幅过长,列举大纲如下:

一、指令directive概述

指令可以对元素绑定事件监听或者改变DOM结构而使HTML拥有像jQuery一样效果具有交互性。不同于jQuery,Angular设计核心思想是通过数据与模板的绑定,
摆脱繁琐的DOM操作,而将注意力集中在业务逻辑上。

几种常见指令ng-app 指令用来指定ng的作用域是在那个标签以内部分(<html ng-app="myApp">标签) ng-repeat迭代器指令可以重复标记元素、

ng-show指令可以根据条件是否显示一个元素、ng-model指令具有双向数据绑定特性、ng-controller 用来声明一个需要和数据进行绑定的模板区域

二、自定义指令directive之模式匹配restrict

直接上代码体验一把,index.html

<!DOCTYPE html>
<html ng-app="myModule">
    <head>
        <meta charset="UTF-8">
        <title>Angular指令--自定义标签</title>
        <script type="text/javascript" src="framework/1.3.0.14/angular.js"></script>
    </head>
    <body>
        <hello></hello>
        <div hello></div>
        <div class=‘hello‘></div>
        <!-- directive:hello -->
        <div></div>

        <!--代码模板template-->
        <script type="text/ng-template" id="hello_Angular.html">
            <p>Hello Angular</p>
        </script>
        <!--代码模板template-->
    </body>
</html>

指令Directive.js

<script type="text/javascript">
        //调用angular对象的module方法来声明一个模块,模块的名字和ng-app的值对应
		var myModule = angular.module(‘myModule‘,[]);
		/* restrict 属性值说明  <推荐使用EA>
		 * E--element元素 <hello></hello>
		 * A--attribute 属性 <div hello></div>
		 * C-class 样式类  <div class="hello"></div>
		 * M 注释   <!-- directive:hello -->
		 */
		//指令--对元素绑定事件监听或者改变DOM
		myModule.directive(‘hello‘, function(){
			return {
				restrict: ‘EACM‘,
				templateUrl:‘hello_Angular.html‘,
				/*template : ‘<p>Hello Angular</p>‘,*/
				replace: true
			}
		})
</script>

===================================================================================
restrict---匹配模式说明, 英文意思是"限制;约束;限定",这里指的是匹配我自定义的标签
===================================================================================

  • E  元素(element)   <hello></hello>
  • A  属性(attribute)  <div hello></div>
  • C  样式类(class)     <div class="hello"></div>
  • M  注释                     <!-- directive:hello -->         注意!!!空格(不常用)

温馨tips: 推荐使用EC或EA匹配模式

replace 是否替换元素的模式 replace:true浏览器DOM结构如下

replace:false 或没有replace属性时浏览器DOM结构如下

三、指令之嵌套变换transclude

<!DOCTYPE html>
<html ng-app="myApp">
	<head>
		<meta charset="UTF-8">
		<title>transclude 嵌套变换</title>
		<script type="text/javascript" src="framework/1.3.0.14/angular.js"></script>
	</head>
	<body>
		<hello>这里是内容哦.....</hello>
		<div hello>这里是内容哦hello....</div>
		<script type="text/javascript">
			var myApp = angular.module(‘myApp‘, []);
			myApp.directive(‘hello‘,function(){
				return {
					restrict: ‘EA‘,
					template: ‘<p>Hello World!!!<b ng-transclude></b></p>‘,
					transclude: true, /*嵌套变换*/
					replace: true /*替换*/
				}
			})
		</script>
	</body>
</html>

四、指令directive运行原理

五、指令配置参数说明

myModule.directive(‘namespaceDirectiveName‘, function factory(injectables) {
        var directiveDefinitionObject = {
            restrict: string,//指令的使用方式,包括标签,属性,类,注释
            priority: number,//指令执行的优先级
            template: string,//指令使用的模板,用HTML字符串的形式表示
            templateUrl: string,//从指定的url地址加载模板或<script type="text/ng-template" id="string"></script>
            replace: bool,//是否用模板替换当前元素,若为false,则append在当前元素上
            transclude: bool,//是否将当前元素的内容转移到模板中
            scope: bool or object,//指定指令的作用域
            controller: function controllerConstructor($scope, $element, $attrs, $transclude){...},//定义与其他指令进行交互的接口函数
            require: string,//指定需要依赖的其他指令

            link: function postLink(scope, iElement, iAttrs) {...},//以编程的方式操作DOM,包括添加监听器等
            compile: function compile(tElement, tAttrs, transclude){
                return: {
                    pre: function preLink(scope, iElement, iAttrs, controller){...},
                    post: function postLink(scope, iElement, iAttrs, controller){...}
                }
            }//编程的方式修改DOM模板的副本,可以返回链接函数

        };
        return directiveDefinitionObject;
});

六、指令与控制器的交互

index.html 如下

<!DOCTYPE html>
<html ng-app="myApp">
	<head>
		<meta charset="UTF-8">
		<title>Directive指令与Controller控制器交互</title>
		<!--引入js库anglarjs-->
		<script type="text/javascript" src="framework/1.3.0.14/angular.js"></script>
        <script type="text/javascript" src="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 === loadData()*/
				//属性方式 注意坑!!! 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()方法会从所有控制器中找到多对应的方法。这就实现了指令的复用。

七、指令与指令的交互

代码过长开始折叠 index.html

<!DOCTYPE html>
<html ng-app="myModule">
	<head>
		<meta charset="UTF-8">
		<title>directive指令与directive指令之间的交互</title>
		<!--引入第三方样式库bootstrap.min.css-->
		<link rel="stylesheet" href="framework/bootstrap-3.0.0/css/bootstrap.min.css" />
		<!--引入js库anglarjs-->
		<script type="text/javascript" src="framework/1.3.0.14/angular.js"></script>
		<script type="text/javascript" src="js/Directive&Directive.js"></script>
	</head>
	<body>
		<div class="row">
	        <div class="col-md-3">
	            <superman strength>动感超人---力量</superman>
	        </div>
	    </div>
	    <div class="row">
	        <div class="col-md-3">
	            <superman strength speed>动感超人2---力量+敏捷</superman>
	        </div>
	    </div>
	    <div class="row">
	        <div class="col-md-3">
	            <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 class="btn btn-primary" 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 “@” 把当前属性作为字符串传值

<!DOCTYPE html>
<html ng-app="myModule">
	<head>
		<meta charset="UTF-8">
		<title>scope绑值策略一.‘@‘把当前属性作为字符串传值</title>
		<!--引入js库anglarjs-->
		<script type="text/javascript" src="framework/1.3.0.14/angular.js"></script>
		<script type="text/javascript" src="js/[email protected]"></script>
	</head>
	<body>
		<div ng-controller="myAppCtrl">
			<drink flavor="{{ctrFlavor}}"></drink>
		</div>
	</body>
</html>

[email protected]

var myModule = angular.module(‘myModule‘, []);
myModule.controller(‘myAppCtrl‘,[‘$scope‘, function($scope){
	console.log($scope);
	$scope.ctrFlavor = "百事可乐";
}]);

myModule.directive(‘drink‘, function(){
	return {
		restrict: ‘AE‘,
		scope: { /*独立scope作用域*/
			flavor: ‘@‘
		},
		replace:true,
		template: ‘<p>{{flavor}}</p>‘
		//使用link进行指令和控制器两个作用域中数据的绑定。
		//如果用scope中@的话,就不需要link这么麻烦了,angularJS会自动进行绑定
		/*,
		link:function(scope,element,attrs){
			element.bind(‘mouseenter‘, function(){
			})
			scope.flavor = attrs.flavor;
		}*/
	}
})

scope “=” 与父scope属性进行双向绑定

index.html

<!DOCTYPE html>
<html ng-app="myModule">
	<head>
		<meta charset="UTF-8">
		<title>scope绑值策略二.‘=‘与父scope中的属性进行双向绑定</title>
		<!--引入第三方样式库bootstrap.min.css-->
		<link rel="stylesheet" href="framework/bootstrap-3.0.0/css/bootstrap.min.css" />
		<!--引入js库anglarjs-->
		<script type="text/javascript" src="js/scope=.js"></script>
	</head>
	<body>
		<div ng-controller="myModuleCtrl" class="col-sm-6">
			<p>{{describe}}</p>
			Ctrl--控制器:<br />
			<input type="text" ng-model="ctrFlavor" class="form-control" />
			<br />
			<p>{{ctrFlavor}}</p>
			Directive--指令:<br />
			<drink flavor="ctrFlavor"></drink>
			<p>{{flavor}}</p>
		</div>
	</body>
</html>

scope=.js

var myModule = angular.module(‘myModule‘, []);
myModule.controller(‘myModuleCtrl‘,[‘$scope‘, function($scope){
	$scope.describe = "scope绑值策略二.=与父scope中的属性进行双向绑定";
	$scope.ctrFlavor = "可口可乐";
}]);

//=与父scope中的属性进行双向绑定
myModule.directive(‘drink‘,function(){
	return {
		restrict: ‘EA‘,
		scope: { /*ng-isolate-scope 隔离作用域*/
			flavor : ‘=‘
		},
		template: ‘<input type="text" class="form-control" ng-model="flavor"  />‘
		/*replace:true*/
	}
}); 

这个例子中有两个输入框,第一个绑定了myModuleCtrl控制器中的scope对象的ctrlFlavor 属性。

第二个绑定的是指令中的flavor属性。但是在drink 指令中 scope对象的flavor 属性 用了 ”=“ ,

与父scope中的属性进行双向数据绑定。所以两个值有一个改动,另一个属性值也会改动。 简单理解为把两个存放数据仓库给相等 A1 == B1

scope&  ‘&‘传递一个来自父scope的函数,稍后调用

index.html

<!DOCTYPE html>
<html ng-app="myModule">
	<head>
		<meta charset="UTF-8">
		<title>scope绑值策略三.‘&‘传递一个来自父scope的函数,稍后调用</title>
		<!--引入第三方样式库bootstrap.min.css-->
		<link rel="stylesheet" href="framework/bootstrap-3.0.0/css/bootstrap.min.css" />
		<!--引入js库anglarjs-->
		<script type="text/javascript" src="js/scope&.js"></script>
	</head>
	<body>
		<div ng-controller="myModuleCtrl">
			<greeting greet="sayHello(name)"></greeting>
			<greeting greet="sayHello(name)"></greeting>
			<greeting greet="sayHello(name)"></greeting>
		</div>
		<!--代码模板template-->
		<script type="text/ng-template" id="sayHello.html">
			<div class="col-sm-12 container">
			    <form role = "form">
				    <div class = "form-group">
				     	<input type="text" class="form-control" ng-model="userName"  />
				        <button class="btn btn-primary" ng-click="greet({name:userName})">Greeting</button>
				    </div>
		        </form>
		    </div>
		</script>
		<!--代码模板template-->
	</body>
</html>

scope&.js

var myModule = angular.module(‘myModule‘, []);
myModule.controller(‘myModuleCtrl‘,[‘$scope‘, function($scope){
	$scope.sayHello = function(name){
		console.log(‘Hello‘+name);
	}
}]);
myModule.directive(‘greeting‘, function(){
	return {
		restrict: ‘EA‘,
		scope: { /*‘&‘传递一个来自父scope的函数,稍后调用*/
			greet : ‘&‘
		},
		templateUrl: ‘sayHello.html‘
	}
});

【资料参考】

http://www.cnblogs.com/lvdabao/tag/AngularJs/

http://angularjs.cn/T001

时间: 2024-12-18 22:02:35

Angular之指令Directive系列的相关文章

angular 自定义指令 directive transclude 理解

项目中断断续续的用了下angular,也没狠下心 认真的学习.angular 特别是自定义指令这块 空白. transclude 定义是否将当前元素的内容转移到模板中.看解释有点抽象. 看解释有点抽象Demo: <!DOCTYPE html> <html lang="en" ng-app='myApp'> <head> <meta charset="UTF-8"> <title>Angularjs</

Angular JS (指令 directive)

一,指令的创建 /*--Js code--*/var app = angular.module("superhero",[]);app.directive("superman",function(){return { restrict: "E", template: "<div> Here I am to save the day </div>"}}) /*--HTML code--*/<div

Angular自定义指令(directive)

angular自定义指令,意我们可以通过angula自己定义指令,来实现我们的特殊要求,为所欲为,一支穿云箭,千军万马来相见 多少年的老规矩了,先看代码: 1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <meta http-equiv="X-UA-Compatible" content=&quo

angular 自定义指令详解 Directive

在angular中,Directive,自定义指令的学习,可以更好的理解angular指令的原理,当angular的指令不能满足你的需求的时候,嘿嘿,你就可以来看看这篇文章,自定义自己的指令,可以满足你的各种需求的指令. 本篇文章的参考来自  AngularJS权威指南 , 文章中主要介绍指令定义的选项配置 废话不多说,下面就直接上代码 //angular指令的定义,myDirective ,使用驼峰命名法 angular.module('myApp', []) .directive('myDi

-_-#【Angular】自定义指令directive

AngularJS学习笔记 <!DOCTYPE html> <html ng-app="Demo"> <head> <meta charset="utf-8"> <title></title> </head> <body> <script src="jquery-1.8.3.min.js"></script> <scrip

AngularJs 指令directive之require

controller的用法分为两种情形,一种是require自定义的controller,由于自定义controller中的属性方法都由自己编 写,使用起来比较简单:另一种方法则是require AngularJS内建的指令,其中大部分时间需要require的都是ngModel这个指令. 在自定义Angular指令时,其中有一个叫做require的字段,这个字段的作用是用于指令之间的相互交流.举个简单的例子,假如我们现在需要编写两 个指令,在linking函数中有很多重合的方法,为了避免重复自己

angular自定义指令-1

1.angular指令感觉就相当于写一个组件,扩展html的语法,比如你写了一个图片上产的组件input-image,引用的时候直接用指令引 <input-image ng-model="image_url"></input-image> 用就好 2.如何写angular指令,主要就是调用directive方法api,方法内返回一个包装特定属性对象 3.angular指令开始compile结束link 4.从外部像指令传递数据,有叫绑定策略,传递数据的主要有两种

angular自定义指令命名的那个坑

Directive 先从定义一个简单的指令开始. 定义一个指令本质上是在HTML中通过元素.属性.类或注释来添加功能.AngularJS的内置指令都是以ng开头,如果想自定义指令,建议自定义一个前缀代表自己的命名空间.这里我们先使用my作为前缀: var myApp = angular.module('myApp', []) .directive('myDirective', function() { return { restrict: 'A', replace: true, template

Angular学习-指令入门

1.指令的定义 从用户的角度来看,指令就是在应用的模板中使用的自定义HTML标签.指令可以很简单,也可以很复杂.AngularJS的HTML编译器会解析指令,增强模板的功能.也是组件化未来的发展趋势,目前HTML5中也加入了很多新标签,但是在实际业务开发过程中,有很多复用的模板,加上复用的交互效果,可以将其编写为AngularJS的指令,开发工程师可以在同一个项目,或多个项目中使用,实现开发一次,到处使用的目标. 2.内置指令和自定义指令 AngularJS内部指令都是ng-diretivena