100字范文,内容丰富有趣,生活中的好帮手!
100字范文 > AngularJS使用directive自定义指令

AngularJS使用directive自定义指令

时间:2018-09-11 13:00:44

相关推荐

AngularJS使用directive自定义指令

AngularJS使用directive自定义指令

directive

除了AngularJS的内置指令,我们也可以通过.directive来创建自定义的指令。

app.directive("myDir",function(){return {template:"<h1>这是自定义指令</h1>"}})

命名

AngularJS要求自定义的Directive命名使用驼峰式语法。也就是从第二个单词开始,每个单词首字母大写,并且不用任何连接符号。

参数

restrict:String,priority:Number,terminal:Boolean,template:String or Template Function,templateUrl:String or Template Function,replace:Boolean or String,transclude:Boolean,scope:Boolean or Object,controller:String or function(scope, element, attrs, transclude, otherInjectables) { ... },controllerAs:String,require:String,link: function(scope, iElement, iAttrs) { ... },compile:function(tElement, tAttrs, transclude) {return {pre: function(scope, iElement, iAttrs, controller) { ... },post: function(scope, iElement, iAttrs, controller) { ... }}return function postLink(...) { ... }}

这里是Directive的所有参数,下面我们主要介绍一下常用的参数restrict,template,scope,link,compile

组合使用例子

my-Directive

restrict

restrict描述了我们怎么使用自定义指令,以上面自定义的myDir为例

EAC可以组合使用

<body ng-controller="myCtrl"><my-dir></my-dir><div my-dir></div><script>angular.module('myApp', []).controller("myCtrl", function($scope) {}).directive("myDir", function() {return {template: "<h1>这是自定义指令</h1>",restrict: "EA"}});</script></body>

scope

scope:为directive指定相关联的作用域

false和true

<!DOCTYPE html><html ng-app ="myApp"><head><meta charset="utf-8"><script src="http://cdn./libs/angular.js/1.4.6/angular.min.js"></script><style>body{border: 5px solid #FF851B;padding: 10px;}.info{color:#0074D9;}.age{color:#FF4136;}</style></head><body ng-controller="myCtrl"><div><my-dire></my-dire></div><div class="my-dirc"></div><button ng-click="changeMyinfo()">changeInfo</button><script>angular.module('myApp', []).controller("myCtrl", function($scope) {$scope.myage = 16;$scope.myInfo = {name:"chenjy"};$scope.changeMyinfo = function(){$scope.myage++;$scope.myInfo.name += "_";}}).directive("myDire", function() {return {template:"<h3>directive E</h3><div>my name:<span class='info'>{{myInfo.name}}</span>,my age:<span class='age'>{{myage}}</span></div>",restrict:"E",scope:false};}).directive("myDirc", function() {return {template:"<h3>directive C</h3><div>my name:<span class='info'>{{myInfo.name}}</span>,my age:<span class='age'>{{myage}}</span></div><div><input type='text' ng-model='myInfo.name'/><input type='text' ng-model='myage'/></div>",restrict:"C",scope:true};})</script></body></html>

我们点击button会发现directive E``directive C的值都会发生变化, 修改age对应的input框只有directive C的age会发生变化

@=&

What is the difference between '@' and '=' in directive scope in AngularJS?

scope{}时,用三者的主要区别为

@传递的是字符串不是对象

<!DOCTYPE html><html><head><meta charset="utf-8"><script src="http://cdn./libs/angular.js/1.4.6/angular.min.js"></script><style>.app{border: 5px solid #FF851B;padding: 10px;}.info{color:#0074D9;}.age{color:#FF4136;}</style></head><body ng-controller="myCtrl"><div ng-app="App" ng-controller="Ctrl" class="app"><div ng-repeat = "info in infoList"><my-dir name="info.name" age="{{info.age}}" change-age="changeAge(info)"></my-dir></div></div><script>angular.module("App", []).controller("Ctrl", ["$scope","$log","$sce",function($scope,$log, $sce) {$scope.infoList = [{name:"chenjy",age:16},{name:"tom",age:17},{name:"jerry",age:18}];$scope.changeAge = function(info){info.age++;}$scope.showLog = function(name){$log.info(name);}}]).directive("myDir", function() {return {template:"<div>"+" <button ng-click='changeAge(info)'>changeAge</button>&nbsp;name:"+" <input type='text' ng-model='name'/>&nbsp;age:"+" <span class='age'>{{age}}</span>"+"</div>",restrict:"E",scope:{name:"=",age:"@",changeAge:"&"}};});</script></body></html>

//html<my-dir new-name="info.name" naw-age="{{info.age}}" change-age="changeAge(info)"></my-dir>//directivescope:{name:"=newName",age:"@nawAge",changeAge:"&"}

两种写法是相同的

@也可以定义在link

.directive("myDir", function() {return {template:"<div>"+" <button ng-click='changeAge(info)'>changeAge</button>&nbsp;name:"+" <input type='text' ng-model='name'/>&nbsp;age:"+" <span class='age'>{{age}}</span>"+"</div>",restrict:"E",scope:{name:"=",/*age:"@",*/changeAge:"&"},link:function(scope, iElement, iAttrs){//scope.age = iAttrs.age; 这么写 只有在第一次加载的时候等于`scope age`但是不会随着changeAge事件更新iAttrs.$observe('age', function(value) {scope.age = value;}) }};});

如果用使用&绑定函数传参数需要json 否则会报错

TypeError: Cannot use 'in' operator to search for 'editWebsite' in 1

template:"<div>"+" <button ng-click='changeAge({age:age})'>changeAge</button>&nbsp;name:"+" <input type='text' ng-model='name'/>&nbsp;age:"+" <span class='age'>{{age}}</span>"+"</div>"

compile、link

在使用前我们先简单了解一下下面两个阶段-编译和链接阶段

第一个阶段是编译阶段,AngularJS会递归的遍历DOM,并从JavaScript中的指令定义知道需要执行的操作。

如图(from stackoverflow)所示原始DOM模板作为函数的参数传给compile编译函数,编译后会返回它的实例。我们有机会在它被返回前对DOM模板进行操作。

1.1 我们以ng-repeat为例,HTML中生成的重复元素就是DOM模板的实例。实例有多个但是模板元素只有一个。

<body ng-controller="myCtrl"><div ng-app="App" ng-controller="Ctrl" class="app"><div ng-repeat="info in infoList"><my-dir info ="info"></my-dir></div><script>angular.module("App", []).controller("Ctrl", ["$scope",function($scope) {$scope.infoList = [{name:"chenjy",age:16},{name:"tom",age:17},{name:"jerry",age:18}];}]).directive("myDir", function() {return {template:"<span>{{info.name}}:</span>",restrict:"E",scope:{info:"=" },compile:function(tELe ,tAttrs,transcludeFn){// 对原始DOM模板进行操作tELe.append(angular.element("<span class='age'>{{info.age}}</span>"));return{pre:function(scope, iElement, iAttrs, controller){},post:function(scope, iElement, iAttrs, controller){}}}};});</script></body>

第二个阶段是链接阶段,链接函数link将模板与作用域链接起来。负责设置事件监听器、监视数据变化和实时的DOM操作。

如果定义了编译函数compile它会返回pre-linkpost-link函数

如果只定义了链接函数link,则会被视为post-link

If you create a directive that only has alinkfunction, AngularJS treats the function as apost-linkfunction. Hence the reason to discuss it here first.

post-link会和前面DOM遍历相反的顺序调用。这个顺序保证所有子元素的post-link在父元素post-link运行时都已经被执行了。

pre-link是AngularJS提供了一个额外的钩子。它可以让你在子元素的post-link函数之前运行你的代码。

post-link被认为是最安全的,因为此时所有子元素都已经被编译compile并且所有子元素的pre-linkpost-link都已经执行结束。

所以这里是自定义指令最常用的地方,大多数情况下我们只需要编写link函数即可

.directive("myDir", function() {return {template:"<span>{{info.name}}:</span>"+"<span class='age'>{{info.age}}</span>",restrict:"E",compile:function(tELe ,tAttrs,transcludeFn){return{// 子元素被链接之前执行pre:function(scope, iElement, iAttrs, controller){},// 子元素被链接之后执行post:function(scope, iElement, iAttrs, controller){// 绑定DOM事件iElement.on('click',function(){ scope.$apply(function(){ scope.infoList[0].name += "_"; scope.infoList[0].age ++; }); });}}}};});

等于下面这种写法

.directive("myDir", function() {return {template: "<span>{{info.name}}:</span>" +"<span class='age'>{{info.age}}</span>",restrict: "E",link: function(scope, iElement, iAttrs) {iElement.on('click', function() {scope.$apply(function() {scope.infoList[0].name += "_";scope.infoList[0].age++;});});}};});

一直被关注的input

<body ng-controller="myCtrl"><div ng-app="App" ng-controller="Ctrl" class="app"><input type="text" focus-me="{{shouldBeFocus}}"></div><script>angular.module("App", []).controller("Ctrl", function($scope) {$scope.shouldBeFocus = true;}).directive('focusMe', function() {return {link: function(scope, element, iAttrs) {iAttrs.$observe("focusMe", function(value) {element[0].focus();});element.bind("blur", function() {scope.$apply(function() {scope.shouldBeFocus = !scope.shouldBeFocus;});});}};});</script></body>

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。