这篇文章主要介绍了Angular1.x复杂指令的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。
具体如下:
名称 | 描述 |
---|---|
compile | 指定一个编译函数 |
controller | 为指令创建一个控制器函数 |
link | 为指令指定链接函数 |
replace | 指定模板内容是否替换指令所应用到的元素 |
require | 声明对某个控制器的依赖 |
restrict | 指定指令如何使用ACEM |
scope | 为指令创建一个新的作用域或者一个隔离的作用域 |
template | 指定一个将被插入到HTML文档的模板 |
templateUrl | 指定一个将被插入到HTML文档的外部模板 |
transclude | 指定指令是否被用于包含任意内容 |
.directive('unorderedList', function () { return { link: function (scope, element, attrs) { var data = scope[attrs['unorderedList'] || attrs['listSource'] ]; var propertyName = attrs['listProperty'] || "price || currency"; if(angular.isArray(data)){ var listElem = angular.element("<ul>"); if(element[0].nodeName == "#comment"){ element.parent().append(listElem); }else{ element.append(listElem); } for(var i=0, len=data.length; i<len; i++){ var itemElem = angular.element('<li>').text(scope.$eval(propertyName, data[i])); listElem.append(itemElem); } } }, restrict:'EACM' }; });
如何使用指令
当作元素使用(E)
<unordered-list list-source="products" list-property="price | currency" />
当unordered-list当作元素使用,需要添加另外的属性代替unordered-list属性的作用。
var data = scope[attrs['unorderedList'] || attrs['listSource'] ];
当作属性使用(A)
<div unordered-list="products" list-property="price | currency"></div>
当作类的属性值使用(C)
<div class="unordered-list: products" list-property="price | currency"></div>
当作注释使用(M)
<!-- directive: unordered-list products -->
使用模板指令
.directive('unorderedList', function () { return { link: function (scope, element, attrs) { scope.data = scope[attrs['unorderedList']]; }, restrict: 'A', template:"<ul><li ng-repeat='item in data'>{{item.price | currency}}</li></ul>" }; });
使用函数作为模板
template属性除了使用字符串,也可以指定一个函数来生成模板化的内容。该函数传入两个函数(指令所应用到的元素以及属性集合)并返回将被插入到文档中的HTML代码片段。
<script type="text/javascript" id="listTemplate"> <ul> <li ng-repeat="item in data">{{item.price | currency}}</li> </ul> </script> <script> var myApp = angular.module('myApp', []) .controller('myCtrl', ["$scope", function ($scope) { $scope.products = [ { name: "Apples", category: "Fruit", price: 1.20, expiry: 10 }, { name: "Bananas", category: "Fruit", price: 2.42, expiry: 7 }, { name: "Pears", category: "Fruit", price: 2.02, expiry: 6 } ]; }]) .directive('unorderedList', function () { return { link: function (scope, element, attrs) { scope.data = scope[attrs['unorderedList']]; }, restrict: 'A', template:function () { return angular.element( document.querySelector("#listTemplate") ).html(); } }; }); </script>
使用外部模板
itemTemplate.html
<p>This is the form the template file</p> <ul> <li ng-repeat="item in data">{{item.price | currency}}</li> </ul>
.directive('unorderedList', function () { return { link: function (scope, element, attrs) { scope.data = scope[attrs['unorderedList']]; }, restrict: 'A', templateUrl:"itemTemplate.html" }; });
通过函数选择一个外部模版
tableTemplate.html
<table> <thead> <tr> <th>Name</th> <th>Price</th> </tr> </thead> <tbody> <tr ng-repeat="item in data"> <td>{{item.name}}</td> <td>{{item.price | currency}}</td> </tr> </tbody> </table>
<div unordered-list="products" template="table" class="table table-striped"> This is where the list will go </div>
.directive('unorderedList', function () { return { link: function (scope, element, attrs) { scope.data = scope[attrs['unorderedList']]; }, restrict: 'A', templateUrl: function (elem, attrs) { return attrs['template'] == "table" ? "tableTemplate.html" : "itemTemplate.html"; } }; });
table-striped样式并没有起作用,设置replace属性为true后的效果是模版内容将替换掉指令所应用到的div元素。
管理指令的作用域
为每个指令实例创建自己的作用域
设置scope属性为true将允许我们在同一个控制器里复用这个指令,可以避免指令共享数据值。
<div class="panel panel-default"> <div class="panel-body" scope-demo></div> <div class="panel-body" scope-demo></div> </div>
var myApp = angular.module('myApp', []) .controller('myCtrl', ["$scope", function ($scope) { $scope.data = {name:"Staven"}; $scope.city = "China" }]) .directive('scopeDemo', function () { return { template: function () { return angular.element(document.querySelector("#scopeTemplate")).html(); }, scope:true }; });
data.name这个属性是在一个对象上定义的,意味着这个值将会在指令的哥哥实例之间所共享,而且所有相应的视图会同步更新。
city是直接在控制器的作用于上被直接赋值的,意味着这个值只在此指令的作用域上有效。
创建隔离的作用域
对于在一个对象上定义的属性,可能会被其他人改变。解决方法就是创建一个隔离的作用域,就是Angularjs为指令的每个实例创建一个独立的作用域的地方,但是这个作用域并不继承自控制器的作用域。当scope定义属性被设置为一个对象时,可创建一个隔离的作用域。隔离的作用域的最基本类型是用一个没有属性的对象表示。
.directive('scopeDemo', function () { return { template: function () { return angular.element(document.querySelector("#scopeTemplate")).html(); }, scope:{} }; });
当创建在不同情况下复用的指令时,隔离的作用域是一种重要的构件时。因为它防止了在控制器作用域和指令之间出现了意料外的交互。但是完全隔绝一个指令会使得难以输入和输出数据。
隔绝的作用域允许使用应用于指令旁边的元素上的属性将数据值绑定到控制器作用域上。
单向绑定@:
向以@为前缀的作用域对象上增添一个属性,以在一个隔离的作用力创建一个单向绑定。
<body ng-app="myApp" ng-controller="myCtrl"> <div class="panel panel-default"> <div class="panel-body"> Direct Binding:<input ng-model="data.name" /> </div> <div class="panel-body" scope-demo nameprop="{{data.name}}"></div> </div> </body> <script type="text/ng-template" id="scopeTemplate"> <div class="panel-body"> <p>Data Value:{{local}}</p> </div> </script> <script> var myApp = angular.module('myApp', []) .controller('myCtrl', ["$scope", function ($scope) { $scope.data = {name:"staven"}; }]) .directive('scopeDemo', function () { return { template: function () { return angular.element(document.querySelector("#scopeTemplate")).html(); }, scope:{ local:"@nameprop" } }; }); </script>
local属性的值以@为前缀,制定了属性local的值应该从一个来自名为nameprop的特性的单向绑定来获得。
使用一个隔离的作用域使得指令不会继承控制器作用域中的数据。
双向绑定=:
向以=为前缀的作用域对象上增添一个属性,以在一个隔离的作用域里创建一个双向绑定。
在隔离作用于上的单向绑定总是被计算作字符串值,如果想访问一个数组,就必须使用双向绑定。
<div class="panel panel-default"> <div class="panel-body"> Direct Binding:<input ng-model="data.name" /> </div> <div class="panel-body" scope-demo nameprop="data.name"></div> </div> <script type="text/ng-template" id="scopeTemplate"> <div class="panel-body"> <p>Data Value:<input ng-model="local" /></p> </div> </script> <script> scope:{ local:"=nameprop" } </script>
使用单向绑定时,提供了一个被"{{"和"}}"字符所包围的绑定表达式,但是angularjs需要知道在双向绑定中哪个属性需要被更新,所以不需要被"{{"和"}}"包围。
计算表达式&:
向以&为前缀的作用域对象上增添一个属性,在父作用域的上下文计算一个表达式。
<body ng-app="myApp" ng-controller="myCtrl"> <div class="panel panel-default"> <div class="panel-body"> Direct Binding:<input ng-model="data.name" /> </div> <div class="panel-body" scope-demo city="getCity(data.name)" nameprop="data.name"></div> </div> </body> <script type="text/ng-template" id="scopeTemplate"> <div class="panel-body"> <p>Name:{{local}}, City:{{cityFn()}}</p> </div> </script> <script> var myApp = angular.module('myApp', []) .controller('myCtrl', ["$scope", function ($scope) { $scope.data = {name:"staven",defaultCity:"hefei"}; $scope.getCity = function (name) { console.log(1); return name == 'staven' ? $scope.data.defaultCity : "Unknown"; } }]) .directive('scopeDemo', function () { return { template: function () { return angular.element(document.querySelector("#scopeTemplate")).html(); }, scope:{ local:"=nameprop", cityFn:"&city" } }; }); </script>
调用cityFn()时,使用了圆括号,要计算被这个特性所指定的表达式,这是必需的,即使当表达式本身就是一个函数调用时。
使用隔离作用域的数据来计算一个表达式
可以将来自代计算的隔离作用域的数据为控制器作用域表达式的一部分。
<div class="panel-body" scope-demo city="getCity(nameVal)" nameprop="data.name"></div> <script type="text/ng-template" id="scopeTemplate"> <div class="panel-body"> <p>Name:{{local}}, City:{{cityFn({nameVal: local})}}</p> </div> </script>
感谢你能够认真阅读完这篇文章,希望小编分享的“Angular1.x复杂指令的示例分析”这篇文章对大家有帮助,同时也希望大家多多支持亿速云,关注亿速云行业资讯频道,更多相关知识等着你来学习!
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。