我正在研究" collapseText" AngularJS中的指令。它的功能是显示最大值" maxLength"字符和"阅读更多"如果文本太大,则会加载其余文本的选项。
我希望我的指令能够转换文本,包括表达式。
理想情况下,我希望它看起来像这样:
<collapse-text max-length="10">This text will be collapsed</collapse-text>
<collapse-text max-length="10">{{foo}}</collapse-text>
我使用的模板是:
<span>{{lessText}}</span>
<span ng-if="overflow">
<span ng-if="!readMore" style="cursor:pointer" ng-click="toggleReadMore()">...(read more)</span>
<span ng-if="readMore">{{moreText}}</span>
</span>
我的指示如下:
'use strict'
angular.module('myModule')
.directive('collapseText', function($window){
return{
restrict: 'E',
scope: true,
transclude: true,
controller : function($scope){
$scope.toggleReadMore = function(){
$scope.readMore = true;
}
},
link: function(scope, element, attrs, ctrl, transclude){
scope.maxLength = attrs.maxLength;
/* 1. Evaluate transcluded element */
/* 2. Check transcluded element's length */
/* 3. Set lessText, moreText, readMore and overflow */
/* 4. Evaluate this directive's template */
console.log(transclude(scope.$parent, function(compiled){
scope.lessText = compiled.text().substring(0, scope.maxLength);
scope.moreText = compiled.text().substring(0, scope.maxLength);
scope.readMore = false;
scope.overflow = scope.moreText ? true : false;
return compiled.text();
}).text());
},
templateUrl: "templates/collapse-text-template.html"
}
});
通过步骤1-4的正确方法是什么? 我看到的两个症状是:
提前感谢您的帮助!
答案 0 :(得分:1)
在指令的link()
功能中,您必须等到{{foo}}
进行评估后才能使用。这可以通过使用$timeout()
在浏览器的事件循环中安排新任务来完成。我不确定它是否是最干净的解决方案,但至少它是否有效。
以下是$timeout()
的代码和一些小改进:
<div ng-app="myModule" ng-controller="MyController">
<collapse-text max-length="10">This text will be collapsed</collapse-text>
<collapse-text max-length="10">{{foo}}</collapse-text>
</div>
<强> template.html 强>
<span ng-if="!readMore">{{lessText}}</span>
<span ng-if="overflow">
<span ng-if="!readMore && overflow" style="cursor: pointer;" ng-click="toggleReadMore()">...(read more)</span>
<span ng-if="readMore">{{moreText}}</span>
</span>
<强>脚本强>
angular.module('myModule', []).controller('MyController', function($scope){
$scope.foo = 'This text will also be collapsed';
});
angular.module('myModule').directive('collapseText', function($timeout){
return {
restrict: 'E',
scope: true,
transclude: true,
controller: function($scope){
$scope.toggleReadMore = function(){
$scope.readMore = true;
};
},
link: function(scope, element, attrs, ctrl, transclude){
var maxLength = +attrs.maxLength;
var compiled = transclude(scope.$parent);
$timeout(function(){
scope.lessText = compiled.text().substring(0, maxLength);
scope.moreText = compiled.text();
scope.readMore = false;
scope.overflow = scope.moreText.length > maxLength;
});
},
templateUrl: "template.html"
}
});
请注意,此实现不会对$scope.foo
的更新做出反应(即指令不会看到更新并重新呈现)。如果您需要这个,我建议您将内容传递给属性中的指令并实现观察者而不是使用翻译。例如:
angular.module('myModule').directive('collapseText', function(){
return {
restrict: 'E',
scope: {
myContent: '=',
// ...
},
link: function(scope){
scope.$watch('myContent', function(newValue){
if (newValue !== undefined) {
doSomethingWith(newValue);
}
});
},
templateUrl: "template.html"
}
});
答案 1 :(得分:0)
正如Aletheios建议的那样,我想出了一种方法,即通过在转换文本上实现监视和手动转换函数,该函数只是将原始输入存储在本地范围内。 它的实现方式,它将在“lessText”字段中显示原始输入,稍后将由执行其转换的父级处理。此转换将在collapseText指令中触发监视。
我可以想到可能会出现的一些问题,虽然我不完全确定它们,因为我对AngularJS很新:
如果文本长于“maxLength”显示的文本被删除且需要进一步处理,它会起作用吗?例如:
<collapse-text max-length="10" {{myLongVariableName.anotherLongVariableName}}</collapse-text>
此代码不允许带有任何标记的文本。例如:
<collapse-text max-length="20"><b>I am bold</b></collapse-text>
初始测试指出它与纯文本和AngularJS表达式完美配合。
这里需要注意的一点是,我打算在另一个指令中使用此代码,因此{{parent.foo}}
也应该有用。
<div ng-app="myModule" ng-controller="MyController">
<collapse-text max-length="10">This text will be collapsed</collapse-text>
<collapse-text max-length="10">{{foo}}</collapse-text>
</div>
<span ng-if="readMore === false">{{lessText}}</span>
<span ng-if="overflow === true">
<span ng-if="readMore === false" style="cursor:pointer" ng-click="toggleReadMore()">...(read more)</span>
<span ng-if="readMore === true">{{moreText}}</span>
</span>
angular.module("myModule")
.controller('MyController', function($scope){
$scope.foo = 'This text will also be collapsed';
})
.directive('collapseText', function($window){
return{
restrict: 'E',
scope: true,
transclude: true,
controller : function($scope){
$scope.readMore = false;
$scope.toggleReadMore = function(){
$scope.readMore = true;
}
$scope.$watch(
function(){
return $scope.transcluded;
},
function(newValue){
if($scope.transcluded){
$scope.lessText = $scope.transcluded.text().substring(0, $scope.maxLength);
$scope.moreText = $scope.transcluded.text();
$scope.readMore = false || $scope.readMore; //If it was arleady true, do not collapse it again.
$scope.overflow = $scope.moreText ? true : false;
}
}
);
},
link: function(scope, element, attrs, ctrl, transclude){
scope.maxLength = attrs.maxLength;
transclude(scope.$parent, function(transcluded){
scope.transcluded = transcluded;
});
},
templateUrl: "template.html"
}
});
在实施类似的内容时,我非常感谢有关代码和“最佳实践”的进一步反馈。