疑似angularJs父子作用域,實際上卻不是的一個小坑

這幾天做了一個分頁控件,使用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就會向上搜索父作用域。從而 導致了現在的問題。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章