Я хотел бы создать директиву Angular JS для проверки длины строки, если она слишком длинная, чтобы сократить ее с помощью фильтра и показать Angular -UI popover on mouseover.
Где в директиве я должен помещать функциональные возможности, чтобы заставить это работать (ссылка, шаблон или компиляция)?
Вид:
<div myapp-shorten="project">{{project.Description}}</div>
Вот мои первые попытки в этой директиве:
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: "="
}
};
});
Ответ 1
Прежде всего, вы можете изменить фильтр, чтобы он не изменял строку, если ей не нужно
Во-вторых, поскольку вам нужен только фильтр и шаблон popover - достаточно.
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>"
}
})
В качестве альтернативы вы можете использовать комбинацию ng-show
и 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) + '...'
}
}
}
}
})
Третий вариант - фактически использовать компиляцию и $watch на myappShrten.Description, но, похоже, это слишком много для меня.
Ответ 2
Вышеприведенный ответ работает отлично. Но если значение thestring
изменяется, это не будет обновляться по мере компиляции контроллера при первом запуске, а затем не будет обновляться, если значение изменится. Ввод кода в controller
компилируется заранее, но ввод кода в функцию link
позволяет ему обновляться, если значение изменяется. Это мое предпочтительное решение, основанное на решении выше:
Вид:
<shorten thestring="project.Description" thelength="40"></shorten>
Директива:
.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>"
}
});