<html>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.2/angular.js"></script>
<div ng-controller="detail">
<input type="text" ng-model="test">
<label ui-a="test"></label>
</div>
<script>
var app = angular.module('app', [])
.directive('uiA',function() {
return function(scope, element, attr) {
element.addClass('ng-binding').data('$binding', attr.uiA);
scope.$watch(attr.uiA,function uiAWatchAction(value) {
element.html(value + "directive" || '');
});
}
}).controller('detail', ['$scope',function($scope) {
$scope.test = 1
}]);
angular.bootstrap(document, ['app']);
</script>
</html>
这个是最基本的用法其中的指令匹配遵循以下原则
- 使用指令时可以在元素或者属性的前面可以添加x- 和 data-
- 忽略:,-,_分隔符,并且忽略大小写
或者用$compileProvider的directive方法创建指令,方法如下
angular.module('app', []).config(['$compileProvider', function($compileProvider) { $compileProvider.directive({ uiA: function() { return function(scope, element, attr) { element.addClass('ng-binding').data('$binding', attr.uiA); scope.$watch(attr.uiA, function uiAWatchAction(value) { element.html(value || ''); }); } } }); }]);
其中scope.$watch方法是监听对象的属性是否改变,里面的三个参数为
- scope 是angularjs作用域对象
- element 是指令匹配的jqlite对象
- attrs 是存放着这个对象的属性和属性操作的对象
angular.module('app', []).config(['$compileProvider',
function($compileProvider) {
$compileProvider.directive({
uiA: function() {
return {
priority: 0,
terminal:true,
template:'',
templateUrl:'',
restrict:'AE',
scope: {
customer: '='
},
replcae:true,
link: {
pre: function preLink(scope, iElement, iAttrs, controller) {
},
post: function postLink(scope, iElement, iAttrs, controller) {
iElement.addClass('ng-binding').data('$binding', iAttrs.uiA);
scope.$watch(iAttrs.uiA,function uiAWatchAction(value) {
element.html(value || '');
});
}
},
compile: function compile(tElement, tAttrs, transclude) {
return {
pre: function preLink(scope, iElement, iAttrs, controller) { ... },
post: function postLink(scope, iElement, iAttrs, controller) { ... }
}
},
require:'',
transclude:true,
controlleras:'a',
controller: function($scope, $element, $attrs){
}
}
}
});
}]);
- priority权重默认是0,当包含多个指令的时候按照权重从大开始,其中Pre-link方法为从大到小, post-link方法从小到大。当权限相同的时候目前测试结果是按照顺序
- terminal当设置为true的时候比当前权重低的指令会失效,相同的会执行
- template和templateUrl的功能和前面的路由里面的一样
- replcae当true会替换当前指令的元素,false会替换元素innerHTML属性, 使用的时候模板必须有根节点,感觉只有restrict为E时有效
- restrict,AE即匹配属性和元素名称,其中A为仅匹配属性,E为仅匹配元素名称,M匹配注释
<html> <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.2/angular.js"></script> <div g-controller="detail"> <ui-a info="test"></ui-a> </div> <script> angular.module('app', []).config(['$compileProvider', function($compileProvider) { $compileProvider.directive({ uiA: function() { return { restrict: 'E', replace:true, scope: { info: '=info' }, template:'<div>{{info.name}},{{info.sex}}</div>' } } }); }]).controller('detail', ['$scope', function($scope) { $scope.test = {name:'a',sex:'1'}; }]); angular.bootstrap(document, ['app']); </script> </html>
scope设置绑定指令的上下文,使用的时候必须要restrict为E, 当设置为true的时候指令之间是不共用一个上下文,应该默认为false
- {info: '=info'}获取属性为info的对象
- {info: '@info'}获取属性为info的值并且标签里面写成info="{{test}}
- {info: '&info'}里面写表达式,并且可以赋予参数
<html> <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.2/angular.js"></script> <div ng-controller="detail"> {{count}} <ui-a info="count = count + amount"></ui-a> </div> <script> angular.module('app', []).config(['$compileProvider', function($compileProvider) { $compileProvider.directive({ uiA: function() { return { restrict: 'E', scope: { info: '&info' }, controller:function($scope){ $scope.info({amount:11}); } } } }); }]).controller('detail', ['$scope', function($scope) { $scope.count =1; }]); angular.bootstrap(document, ['app']); </script> </html>
controller为当前指令中的控制器对象,里面的第四个参数$transclude可以 设置transclude的元素和compile的第三个参数一样 4.transclude当设置为ture的时候指令原来的html插入到有ng-transclude的属性的元素, 默认为false,当设置为element的时候还未知...
<html> <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.2/angular.js"></script> <div> <ui-a>Check out the contents</ui-a> </div> <script> angular.module('app', []).config(['$compileProvider', function($compileProvider) { $compileProvider.directive({ uiA: function() { return { restrict: 'E', transclude: true, template: '<div class="alert" ng-transclude></div>' } } }); }]); angular.bootstrap(document, ['app']); </script> </html>
- require用于请求其他的指令,在link的第四个参数注入, ^表示在dom模型上面的上一个节点,没有加表示是在同一个元素上面, 同级的不知何解,当前前面加上?表示不存在的时候不报错, 调用另一个控制器只能是声明this后的,如以下代码改成$scope.a=1则调用不到
<html> <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.2/angular.js"></script> <div> <ui-b> <ui-a></ui-a> </ui-b> </div> <script> angular.module('app', []).config(['$compileProvider', function($compileProvider) { $compileProvider.directive({ uiB: function() { return { restrict: 'E', transclude:true, controller: function($scope){ this.a=1; }, template: '<div ng-transclude></div>' } }, uiA: function() { return { require: '^uiB', restrict: 'E', link: function(scope, element, attrs,uiBCtrl) { console.log(uiBCtrl.a); }, template: '' } } }); }]); angular.bootstrap(document, ['app']); </script> </html>
- controlleras控制器的别名
- link里面的post方法就是前面的基本用法,如果存在compile,则link失效, 其中pre为连接前,post为连接后
- compile主要用来处理模板的DOM ,返回的对象是一个link
<html ng-app="compile"><script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.2/angular.js"></script>
<div ng-controller="Ctrl">
<input ng-model="name"> <br>
<textarea ng-model="html"></textarea> <br>
<div compile="html"></div>
</div>
<script>
angular.module('compile', [], function($compileProvider) {
$compileProvider.directive('compile', function($compile) {
//新建一个link方法
return function(scope, element, attrs) {
scope.$watch(
function(scope) {
//判断编译的表达式是否改变
return scope.$eval(attrs.compile);
},
function(value) {
//当编译的表达式改变重写
element.html(value);
//获得控制器的上下文以及表达式重新编译
$compile(element.contents())(scope);
}
);
};
})
});
function Ctrl($scope) {
$scope.name = 'Angular';
$scope.html = 'Hello {{name}}';
}
</script>
</html>