rush:xhtml;">
内容:
自定义指令当然也需要实现这种功能啦。scope属性为对象时,可为自定义指令指定一个可以绑定值的属性。这里还得说明一下的是,这个scope属性与自定义指令里link属性里的scope参数是一个变量。
有了前面的一个示例,下面再来说说绑定策略:即用符号前缀给自定义指令传值。它是一个键值对,键是在自定义指令中使用的,值里符号后面的字符串是html页面自定义指令的属性名;如果值里只有符号,则html页面自定义指令的属性名就是键名。
符号
说明 |
示例 |
页面自定义指令里的val属性的值可传给link的scope使用。第一种写法——str : “@”,这种写法html页面的指令属性名为str属性名为val属性中,数据值可以是任意类型的。第一种写法:name : “=”,这种写法html页面的自定义指令属性名就是name属性名是username一个函数,可以在指令中调用。第一种写法:getName:”&”,这种写法html页面的自定义指令属性名就是gegName属性名是getUserName
其余两种符号用法:
5.controller属性
controller属性用于提供对外的接口,即该自定义指令会被其他自定义指令调用。所谓的接口,就是this后的变量或方法。
controller可以使用的参数,作用域、节点、节点的属性、节点内容的迁移,这些都可以通过依赖注入被传进来,所以你可以根据需要只写要用的参数,有$scope,Z$element,$attrs,$transclude。
调用该自定义指令的指令需要放在该指令之间。假定firstDirective指令是要被调用的自定义指令,expander是调用者指令。如下:
rush:xml;">
既然firstDirective内部还有指令,则firstDirective必须配置transclude属性为true。代码如下:
rush:js;">
//用于被
调用的
自定义指令
app.directive('f
irstDirective',function(){
return {
template : '
',replace : true,transclude : true,controller :function(){
this.getData = function(val){
var data = 3 * val;
return data;
}
this.a = "abc";
}
}
});
调用其他指令的自定义指令必须配置require属性指定指令名。然后在link函数里就可注入要调用的指令。
rush:js;">
//
自定义指令
app.directive('expander',function(){
return {
templateUrl : 'template.html',require : '^?f
irstDirective',//引用其他
自定义指令,^表示从父节点开始找,?表示将告诉$compile服务,如果所需的指令没找到,不要抛出异常
s
cope : {
title : '=attribute'
},link : function(s
cope,element,attris,f
irstDirct){//注入
console.log(f
irstDirct.a)//
调用其他指令的变量
console.log(f
irstDirct.getData(6)) //
调用其他指令的
方法
}
};
});
link后的方法在指令中负责执行DOM 操作和注册事件监听器等。link函数有五个参数(scope,attrs,controller,linker)。link 方法的参数解释:
它与
自定义指令里的s
cope
属性是
一个东西。它是指令s
cope的引用,所以可改名为sco等其他名字。s
cope 变量在初始化时是不被定义的,link
方法会
注册监视器监视值变化事件。
element:
包含指令的DOM元素的引用, link
方法一般通过jQuery 操作实例(如果没有加载jquery,还可以使用Angular's jqLite )。
controller:
在有嵌套指令的情况下使用。这个参数作用在于把子指令的引用提供给父指令,允许指令之间进行交互,如前面的例子。
注意:当调用link 方法时, 通过值传递(”@”)的scope 变量将不会被初始化,它们将会在指令的生命周期中另一个时间点进行初始化,如果你需要监听这个事件,可以使用scope.$watch 方法。
7.link与compile的区别
compile函数有三个参数(cElement,cAttrs,cLinker),使用compile函数可以在ng创建原始dom实例以及创建scope实例之前,改变原始的dom(template element);可以应用于当需要生成多个element实例但只有一个template element的情况,ng-repeat就是一个最好的例子。它就在是compile函数阶段改变原始的dom生成多个原始dom节点,然后每个又生成element实例。因为compile只会运行一次,所以当你需要生成多个element实例的时候是可以提高性能的。
link函数有五个参数(scope,ctrl,linker)。
link又分为pre-link和post-link,在代码里直接用pre和post表示,当我们直接使用link时,默认跟post一样。我在网上找了个例子来说明一下区别,代码如下:
注意打印结果:
Hello
levelTwo: compile =>
Hello
levelThree: compile =>
Hello
levelOne: pre link =>
Hello
levelTwo: pre link =>
Hello
levelThree: pre link =>
Hello
levelThree: post link =>
Hello
levelTwo: post link =>
Hello
levelOne: post link =>
Hello
分析打印结果:
运行levelone指令中的compile函数,ng就会递归遍历它的dom节点,然后在level-two与level-three上面重复这些操作。所以会依次打印连续三个compile。
pre会在所有compile执行完后且在所有post之前执行。这样可以在执行post前执行一些其他代码,有些类似AOP。
由上面结果可知,post的执行顺序却是先levelthree最后levelone,即反向调用相关联的post-link函数。这么做的好处是,当我们运行levelone时,保证leveltwo与levelthree都已经执行过了,这样就会更安全。所以默认的link就是post。
之所以展示这个代码,主要是给一些朋友看看真实的项目,,多余的东西删掉了,具体的注入这里就不在讲了。
html页面代码:
控制器代码:
rush:js;">
"use strict";//严格
define(["application-configuration","s-pagination","tableDataService"],function (app) {
app.register.controller("AppStatisticController",["$scope","$rootScope","$stateParams","$http","tableDataService",function($scope,$rootScope,$stateParams,$http,tableDataService) {
var getTableDataSuccess = function(result) {
if(result.c == 1) {
$scope.title = result.title;
$scope.lists = result.Pagelist;
$scope.total = result.data;
$scope.paginationConf.totalItems = result.total;
}else if(result.c == 2){
//弹出框,没有查到数据
} else {
alert(result.i);
}
};
var getTableDataError = function(result) {
alert(result);
};
/重要的代码,这个paginationConf与自定义指令双向绑定数据/
$scope.paginationConf = {
currentPage: 1,itemsPerPage: 10,pagesLength: 9,search: false,onChange: function() {
var param = {
"pageNo": this.currentPage,"pageSize": this.itemsPerPage,"timeType": $scope.formData.timeType,"adStyle":$scope.formData.adStyle,};
param.appId = $stateParams.appId;
tableDataService.getTableData(
param,"ims/appStat.do",getTableDataSuccess,getTableDataError
);
}
};
$scope.$watch("formData",function(newValue,oldValue,scope) {
if(newValue.keywords == oldValue.keywords) {
$scope.paginationConf.search = true;
}
},true);
}]);
});
自定义指令代码:也算是angularJS的分页插件
rush:js;">
/**
*
分页插件封装s-pagination.js
* @date 2016-05-06
* @author Peter
*/
angular.module('s.pagination',[]).directive('sPagination',[function(){//自定义指令
return {
restrict: 'E',//仅限元素名调用
template: '<div class="page-list">' +
'<ul class="pagination" ng-show="conf.totalItems > 0">' +
'<li ng-class="{disabled: conf.currentPage == 1}" ng-click="prevPage()">«' +
'<li ng-repeat="item in Pagelist track by $index" ng-class="{active: item == conf.currentPage,separate: item == \'...\'}" ' +
'ng-click="changeCurrentPage(item)">' +
'{{ item }}' +
'' +
'<li ng-class="{disabled: conf.currentPage == conf.numberOfPages}" ng-click="nextPage()">»' +
'' +
'<div class="page-total" ng-show="conf.totalItems > 0">' +
'第<input type="text" ng-model="jumpPageNum" ng-keyup="jumpToPage($event)"/>页 ' +
'每页<select ng-model="conf.itemsPerPage" ng-options="option for option in conf.perPageOptions ">' +
'/共
{{ conf.totalItems }}
条' +
'
' +
'<div class="no-items" ng-show="conf.totalItems <= 0">暂无数据