這幾天做了一個分頁控件,使用angularJS進行編寫,無奈發現,我的指令中的模板所觸發的點擊事件不會去link函數中找相對應的方法進行調用,而是去他的父作用域進行查找,自然是找不到相關的代碼的,這就導致了點擊控件沒有反應的情況發生。
我的控件代碼如下:
define(['angular','app','bootstrap'], function (angular,app) {
app.directive('pageDirective', ['$rootScope',function ($rootScope) {
return {
restrict: 'E',
templateUrl: 'app/external_library/page_directive/pagination.html',
replace: true,
scope: {
conf: '='
},
link: function (scope, element, attrs) {
scope.page = {};
scope.init = function () {
console.log("初始化分頁控件");
// 初始化一頁展示多少條 默認爲10
scope.conf.pageLimit = [10, 15, 20, 30, 50];
if (!scope.conf.itemPageLimit) {
scope.conf.itemPageLimit = scope.conf.pageLimit[0];
} else {
// 把自定義的條目加入到pagelimit中
if (scope.conf.pageLimit.indexOf(scope.conf.itemPageLimit)) {
scope.conf.pageLimit.push(scope.conf.itemPageLimit);
scope.conf.pageLimit = scope.conf.pageLimit.sort(function (a, b) {
return a - b;
});
}
}
//一共多少頁
scope.page.limit = Math.floor(scope.conf.total / scope.conf.itemPageLimit);
}
// 上一頁
scope.prevPage = function () {
console.log("上一頁");
if (scope.conf.currentPage <= 1) return;
scope.conf.currentPage -= 1;
}
// 下一頁
scope.nextPage = function () {
console.log("下一頁");
if (scope.conf.currentPage >= scope.page.limit) return;
scope.conf.currentPage += 1;
}
// 改變一頁顯示條目
scope.selectPage = function () {
console.log("改變一頁顯示條數");
scope.conf.currentPage = 1;
scope.page.limit = Math.floor(scope.conf.total / scope.conf.itemPageLimit);
}
// 跳轉頁
scope.linkPage = function () {
console.log("跳轉頁");
}
scope.$watch("conf.total", function (newVal) {
if (angular.isUndefined(newVal)) {
scope.conf.total = 0;
scope.conf.currentPage = 1;
} else {
scope.init();
}
});
}
}
}]);
});
模板代碼如下:
<div>
<ul style="white-space:nowrap">
<li ng-disable="conf.currentPage == 1" ng-click="prevPage()" style="display:inline-block;">
<button href="#"><</button>
</li>
<li style="display:inline-block;">
<div>
<div>第<input style="width: 50px;" type="text" ng-model="conf.currentPage" ng-change="linkPage()">頁</div>
</div>
</li>
<li ng-disable="conf.currentPage == page.limit" ng-click="nextPage($event)" style="display:inline-block;">
<button href="#">></button>
</li>
<li style="display:inline-block;">
<div>
<div>
一頁<select ng-options="limit for limit in conf.pageLimit" ng-model="conf.itemPageLimit"
ng-change="selectPage()"></select>條
</div>
</div>
</li>
<li style="display:inline-block;">
<div>共<span>{{page.limit}}</span>頁</div>
</li>
</ul>
</div>
仔仔細細檢查多遍,並沒有發現什麼有可能導致以上問題的錯誤。於是我懷疑是作用域的問題,在查找了一些資料後,發現並不是這個問題,因爲分頁控件的特殊性,他需要一個新的作用域,並且又要將當前頁傳遞出去,做好的做法應該就是這樣了:
return {
restrict: 'E',
templateUrl: 'app/external_library/page_directive/pagination.html',
replace: true,
scope: {
conf: '='
}...
}
在無奈之下,只有妥協,既然他只能找到controller中的方法,那我就給他一個。於是在指令中使用了指定的controller。但是依舊不行。在這個過程中,我發現它能夠進行初始化的操作。也就是說,相關數據其實是可以傳遞進來的,那麼代碼就是沒有問題的。
換個思維,既然代碼沒有問題,那就只能是模板的問題了。我將模板全部刪除,只保留了一個最簡單的button按鈕,綁定了一個最簡單的click事件,打印了一串字符串。一次通過。
這個時候問題就被定位了——就是模板的問題。又細細研讀了自己的模板一次,發現原來是ng-if惹的禍。修改後的代碼如下所示:
<div>
<ul style="white-space:nowrap">
<li ng-disable="conf.currentPage == 1" ng-click="prevPage()" style="display:inline-block;">
<button href="#"><</button>
</li>
<li style="display:inline-block;">
<div>
<div>第<input style="width: 50px;" type="text" ng-model="conf.currentPage" ng-change="linkPage()">頁</div>
</div>
</li>
<li ng-disable="conf.currentPage == page.limit" ng-click="nextPage($event)" style="display:inline-block;">
<button href="#">></button>
</li>
<li style="display:inline-block;">
<div>
<div>
一頁<select ng-options="limit for limit in conf.pageLimit" ng-model="conf.itemPageLimit"
ng-change="selectPage()"></select>條
</div>
</div>
</li>
<li style="display:inline-block;">
<div>共<span>{{page.limit}}</span>頁</div>
</li>
</ul>
</div>
就只差了開頭的一點點,如果在第一次加載指令進行編譯的時候,ng-if會將相關的DOM移除,第二次初始化的時候自然也就沒有了相關的作用域,angular就會向上搜索父作用域。從而 導致了現在的問題。