如何在自定義的directive中使用自定義的filter

2018-06-07 18:06 更新

筆者前兩天在使用AngularJS做一個項(xiàng)目時,遇到這樣一個需求,在一個自定義的directive中使用一個自定義的filter。剛開始我沒有意識到這里面會涉及依賴注入的問題(唉,人蠢沒辦法?。。瑢?dǎo)致走了不少彎路。

下面是具體的代碼。

先是html部分的代碼,


<div ng-app="gxt" ng-controller="index">
    <!-- ... -->
    <site sites="sites" selected="selectedSite" change="changeSite(site)"></site>
    <!-- ... -->
</div>

然后是與之對應(yīng)的js代碼,


var gxt = angular.module('gxt', []);
gxt.controller('index', ['$scope', function($scope) {
    $scope.sites = [{
        "id": "20112",
        "url": "http://www.baidu.com",
        "detected": true
    }, {
        "id": "20113",
        "url": "http://tieba.baidu.com",
        "detected": false
    }, {
        "id": "20114",
        "url": "http://ce.baidu.com",
        "detected": false
    }];
    $scope.changeSite = function(site) {
        console.log(site);
        // TODO do something with change callback
    };
    $scope.$watch('selectedSite', function(nv, ov) {
        console.log(nv, ov);
        // TODO check the model value
    });
}]);

顯然,我這里自定義了一個directive,名字叫做site,其具體的實(shí)現(xiàn)如下,


var directives = angular.module('directives', []);
directives.directive('sites', ['$filter', function ($filter) {
    return {
        restrict: 'EA',
        replace: true,
        scope: {
            sites: '=',
            selected: '=',
            change: '&'
        },
        template: [
            '<div class="site">',
                '<input type="text" class="site-input" ng-model="site" ng-change="manul()" ng-click="show($event)">',
                '<label class="placeholder" ng-show="showPlaceholder">輸入網(wǎng)站url,如:www.baidu.com</label>',
                '<span class="arrow"></span>',
                '<ul class="" ng-show="toggleList">',
                    '<li ng-repeat="site in sites" ng-click="selectSite(site)">[[site.url | pureURL]]</li>',
                '</ul>',
            '</div>'
        ].join(''),
        link: function (scope, element, attrs) {
            scope.toggleList = false;
            scope.showPlaceholder = true;
            scope.show = function(ev) {
                scope.toggleList = true;
                ev.cancelBubble = true;
                ev.preventDefault();
                ev.stopPropagation();
            };
            $(document).on('click', function() {
                scope.$apply(function () {
                    scope.toggleList = false;
                });
            });
            scope.manul = function() {
                scope.showPlaceholder = scope.site ? false : true;
            };
            scope.selectSite = function(site) {
                scope.selected = site;
                scope.site = $filter('pureURL')(site.url);
                // 調(diào)用change回調(diào)
                //scope.change(site);
                scope.change({
                    site: site
                });
            };
        }
    };
}]);

從代碼可以看出,這個site的作用是:接受一個數(shù)組數(shù)據(jù),然后渲染成一個下拉列表樣式的可選項(xiàng),類似下圖,

注意,剛開始這里出現(xiàn)了問題,報(bào)錯信息是site.url | pureURl undefined is not a function。

我很納悶,看報(bào)錯信息的意思應(yīng)該是template中用到的pureURL未定義,但是我在之前的確是定義的了啊,其定義如下,


var filters = angular.module('filters', []);
filters.filter('pureURL', [function () {
    var exports = function (input) {
        if (!input) {
            return '網(wǎng)址不能為空';
        } else {
            return input.replace(/(^(http|https):\/\/)|(\/$)/g, '');
        }
    };
    return exports;
}]);

在求助于google及stackoverflow之后,我猛然意識到,我的directive module中沒有注入filters,這樣在site中當(dāng)然拿不到pureURL了啊。

所以,將directives的定義修改如下,


var directives = angular.module('directives', ['filters']);

然后再修改gxt的聲明如下,


var gxt = angular.module('gxt', ['directives', 'filters']);

其實(shí),這里也可以寫成如下的形式,


var gxt = angular.module('gxt', ['directives']);

即此可以省略filters的注入。因?yàn)樵?code>directives中已經(jīng)注入了filters。

以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號