最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Angular JS Directive - Template, compile or link? - Stack Overflow

programmeradmin5浏览0评论

I would like to create an Angular JS directive to check the length of a string, if it is too long to shorten it using a Filter, and show an Angular-UI popover on mouseover.

Where in the directive should I be placing the functionality to get this to work (link, template or pile)?

The view:

<div myapp-shorten="project">{{project.Description}}</div>

Here are my first attempts at the directive so far:

angular.module('myapp.directives', [])
 .directive('myappShorten', function () {

    function link(scope, element, attrs) {

        var outputText = "";

        if (myappShorten.Description.length > 20) {
            outputText += "<div popover='{{myappShorten.Description}}' popover-trigger='mouseenter'>" +
            "{{myappShorten.Description | cut:true:20:' ...'}}</div>";
        } else {
            outputText += "<div>{{myappShorten.Description}}</div>";
        }

        element.text(outputText);
    }

    return {
        link: link,
        scope: {
            myappShorten: "="
        }
    };

});

I would like to create an Angular JS directive to check the length of a string, if it is too long to shorten it using a Filter, and show an Angular-UI popover on mouseover.

Where in the directive should I be placing the functionality to get this to work (link, template or pile)?

The view:

<div myapp-shorten="project">{{project.Description}}</div>

Here are my first attempts at the directive so far:

angular.module('myapp.directives', [])
 .directive('myappShorten', function () {

    function link(scope, element, attrs) {

        var outputText = "";

        if (myappShorten.Description.length > 20) {
            outputText += "<div popover='{{myappShorten.Description}}' popover-trigger='mouseenter'>" +
            "{{myappShorten.Description | cut:true:20:' ...'}}</div>";
        } else {
            outputText += "<div>{{myappShorten.Description}}</div>";
        }

        element.text(outputText);
    }

    return {
        link: link,
        scope: {
            myappShorten: "="
        }
    };

});
Share Improve this question edited Jan 15, 2016 at 13:31 vittore 17.6k6 gold badges46 silver badges84 bronze badges asked May 20, 2014 at 22:16 Holland RisleyHolland Risley 6,7819 gold badges27 silver badges36 bronze badges 1
  • Perhaps a more prehensive overview of directive functions: Angular directives - when to use pile, controller, pre-link and post-link. – Izhaki Commented Jul 7, 2014 at 16:41
Add a ment  | 

2 Answers 2

Reset to default 4

First of all you can change the filter that it wouldn't alter string if it doesn't need to

Second, since you only need filter and popover - template is enough.

 angular.module('myapp.directives', [])
   .directive('myappShorten', function () {

     return { 
       scope: { data : '=myappShorten',
       template:"<div popover='{{data.Description}}' popover-trigger='mouseenter'>" +
        "{{ data.Description | cut:true:20:' ...' }}</div>"
     }
   })

Alternatively you can use bination of ng-show and ng-hide

 app.directive('shorten', function () {
return {
    restrict: 'A'
    , scope :  {
        shorten : '=',
        thestring: '='   
    }
    , template: "<div ng-show='sCtrl.isLong()' tooltip='{{ sCtrl.str }}'>{{ sCtrl.short() }}</div>"+
                "<div ng-hide='sCtrl.isLong()'>{{ sCtrl.str }}</div>"

    , controllerAs: 'sCtrl'
    , controller: function ($scope) {
        this.str = $scope.shorten || ''
        this.length = $scope.thestring || 20

        this.isLong = function() {
            return this.str.length > this.length   
        }

        this.short = function() {
            if ( this.str.length > this.length)  {
                return this.str.substring(0,this.length)  + '...'                    
            }
        }                                  
    }                               
  }       
})

Third option would be to actually use pile and $watch on myappShrten.Description but it seems to be overkill to me.

The above accepted answer works fine. But if the value of thestring changes this will not update as the controller piles on first run and then will not update if the value changes. Putting code into the controller piles upfront, but putting the code in the link function allows it to update if the value changes. This is my preferred solution inspired by the solution above:

The view:

<shorten thestring="project.Description" thelength="40"></shorten>

The directive:

.directive('shorten', function () {
    return {
        restrict: 'E'
        , scope: {
            thelength: '=',
            thestring: '='
        }
        , link: function postLink(scope, iElement, iAttrs) {
            scope.isLong = function () {
                return scope.thestring.length > scope.thelength
            }

            scope.short = function () {
                if (scope.thestring.length > scope.thelength) {
                    return scope.thestring.substring(0, scope.thelength) + '...'
                }
            }

        }

        , template: "<div class='handCursor' ng-show='isLong()' tooltip='{{ thestring }}'>{{ short() }}</div>" +
                    "<div ng-hide='isLong()'>{{ thestring }}</div>"
    }
});
发布评论

评论列表(0)

  1. 暂无评论