.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> <div scope-demo></div> <div 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> <div> Direct Binding:<input ng-model="data.name" /> </div> <div scope-demo nameprop="{{data.name}}"></div> </div> </body> <script type="text/ng-template"> <div> <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> <div> Direct Binding:<input ng-model="data.name" /> </div> <div scope-demo nameprop="data.name"></div> </div> <script type="text/ng-template"> <div> <p>Data Value:<input ng-model="local" /></p> </div> </script> <script> scope:{ local:"=nameprop" } </script>
使用单向绑定时,提供了一个被"{{"和"}}"字符所包围的绑定表达式,但是angularjs需要知道在双向绑定中哪个属性需要被更新,所以不需要被"{{"和"}}"包围。
计算表达式&:
向以&为前缀的作用域对象上增添一个属性,在父作用域的上下文计算一个表达式。
<body ng-app="myApp" ng-controller="myCtrl"> <div> <div> Direct Binding:<input ng-model="data.name" /> </div> <div scope-demo city="getCity(data.name)" nameprop="data.name"></div> </div> </body> <script type="text/ng-template"> <div> <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()时,使用了圆括号,要计算被这个特性所指定的表达式,这是必需的,即使当表达式本身就是一个函数调用时。
使用隔离作用域的数据来计算一个表达式
可以将来自代计算的隔离作用域的数据为控制器作用域表达式的一部分。