我对Angular的指令很新,并试图弄清楚使用它们的正确方法。我正在使用ng-repeat来填充元素列表。一旦加载了转发器,我想查看每个元素并找到哪个元素是最高的(其中包含最多的文本),然后强制所有元素达到该大小。
在jQuery中实现这一点的方法就是这样:
var tallest = 0;
// Loop through each element
$('.element-class').each(function () {
var thisHeight = $(this).height();
if (thisHeight > tallest)
tallest = thisHeight;
});
// Apply height to all elements
$('.element-class').height(tallest);
是否有人能够指导我如何通过指令(或其他更合适的Angular方式)来实现这一目标。转发器看起来像这样。
<div class="element-class" ng-repeat="item in items">
<div class="element-title" ng-bind="item.title"></div>
<p class="element-text" ng-bind="item.description"></p>
</div>
答案 0 :(得分:5)
这是你能做的。使用指令,您可以跟踪每个元素,并在最终元素上调用一个函数,该函数将计算每个元素的高度并找到最高,然后将所有元素设置为该高度。您将需要使用角度$timeout
,以确保在角度完成操作dom之前不检查高度。这是一些代码,下面我放了一个link to a plunker。
<强> HTML 强>
<div equalize-height>
<div class="element-class" equalize-height-add="item" ng-repeat="item in items">
<div class="element-title" ng-bind="item.title"></div>
<p class="element-text" ng-bind="item.description"></p>
</div>
</div>
<强>角强>
.directive('equalizeHeight', ['$timeout', function($timeout){
return {
restrict: 'A',
controller: function($scope){
console.log('equalizeHeightFor - controller');
var elements = [];
this.addElement = function(element){
console.log('adding element:', element);
elements.push(element);
console.log(elements);
}
// resize elements once the last element is found
this.resize = function(){
$timeout(function(){
console.log('finding the tallest ...');
// find the tallest
var tallest = 0, height;
angular.forEach(elements, function(el){
height = el[0].offsetHeight;
console.log('height:', height);
if(height > tallest)
tallest = height;
// console.log(el);
});
console.log('tallest:', tallest);
console.log('resizing ...');
// resize
angular.forEach(elements, function(el){
el[0].style.height = tallest + 'px';
});
console.log('-- finished --');
}, 0);
};
}
};
}])
.directive('equalizeHeightAdd', [function($timeout){
return {
restrict: 'A',
require: '^^equalizeHeight',
link: function(scope, element, attrs, ctrl_for){
console.log('equalizeHeightAdd - link');
// add element to list of elements
ctrl_for.addElement(element);
if(scope.$last)
ctrl_for.resize();
}
};
}])
这是一个链接到一个plunker也看到它在行动: http://plnkr.co/edit/X4jmwZ?p=preview
答案 1 :(得分:0)
在视图上呈现ng-repeat最后一个元素之后,您需要完全运行代码。
Angular way解决方案如下所示。
<强> HTML 强>
<div class="element-class" on-finish-ng-repeat-render ng-repeat="item in items">
<div class="element-title" ng-bind="item.title"></div>
<p class="element-text" ng-bind="item.description"></p>
</div>
<强>指令强>
app.directive('onFinishNgRepeatRender', function($timeout) {
return {
restrict: 'A',
link: function(scope, element, attr) {
if (scope.$last === true) {
$timeout(function() {
//this coade will execute right after ng-repeat rendering has been completed
var tallest = 0, currentElement = angular.element(element);
// Loop through each element
angular.forEach(angular.element(element), function(value, key) {
var thisHeight = angular.element(value).height();
if (thisHeight > tallest)
tallest = thisHeight;
});
// Apply height to all elements
currentElement.height(tallest);
});
}
}
}
});
希望这可以帮助你,谢谢。
答案 2 :(得分:0)
我想做同样的事。这个帖子对我很有帮助。经过一些麻烦后,我找到了解决方案。
我想要做的就是获取所有元素的长度并将所有元素长度设置为最高。
因此,首先我需要检测ng-repeat何时通过指令完成加载,并且在该指令中,一旦我检测到最后一个已完成加载,我必须找到所有元素的最高长度并将其应用于所有元素元件。
HTML
final class LanguageMapper
{
/**
* @param LanguageTable $languageTable
* @param PackageTable $packageTable
* @param Cache $cache
* @param LoggerInterface $logger
*/
public function __construct(LanguageTable $languageTable, PackageTable $packageTable, Cache $cache, LoggerInterface $logger)
{
$this->languageTable = $languageTable;
$this->packageTable = $packageTable;
$this->cache = $cache;
$this->logger = $logger;
}
/**
* @param array $where
*
* @return array List of active languages
*/
public function findActive(array $where = [])
{
try {
if (empty($where) && $this->cache->hasItem('active_languages')) {
return unserialize($this->cache->getItem('active_languages'));
}
} catch (RuntimeException $exception) {
$this->logger->critical($exception->getMessage(), [
'exception' => $exception,
'file' => $exception->getFile(),
'line' => $exception->getLine(),
]);
}
/* @var $adapter \Zend\Db\Adapter\Adapter */
$adapter = $this->languageTable->getGateway()->getAdapter();
$sql = new Sql($adapter);
$select = $sql->select()->columns([Select::SQL_STAR])
->from('language')
->join('package', 'package.id = language.package', Select::SQL_STAR, Select::JOIN_LEFT)
->where(array_merge($where, ['active' => true]))
->order(['position']);
$selectString = $sql->buildSqlString($select);
$resultSet = $adapter->query($selectString, Adapter::QUERY_MODE_EXECUTE);
$languages = [];
$hydrator = new ArraySerializable();
foreach ($resultSet as $result) {
$language = new Language();
$package = new Package();
$hydrator->hydrate((array) $result, $package);
$hydrator->hydrate((array) $result, $language);
$language->setPackage($package);
$languages[] = $language;
}
if (empty($where)) {
try {
$this->cache->setItem('active_languages', serialize($languages));
} catch (RuntimeException $exception) {
$this->logger->warning($exception->getMessage(), [
'exception' => $exception,
'file' => $exception->getFile(),
'line' => $exception->getLine(),
]);
}
}
return $languages;
}
}
1)<div class="col-lg-4" ng-repeat="category in categoriesList.categories" set-max-height>
<div class="catagory-item">
<h1 class="text-center">{{category}}</h1>
</div>
</div>
是指令名称。
2)set-max-height
是类,通过使用这个类名,我想获得所有元素的高度,并将其设置为所有元素的最大高度。
指令
category-item
答案 3 :(得分:0)
ragamufin's solution就像一个魅力(谢谢!)
但是如果你计划在重复的中间过滤或添加新元素,你应该在'equalizeHeightAdd'指令的末尾松开'if'(否则它不会自己调整大小)并实现一个删除函数在控制器上删除元素(如果它们被销毁):
.directive('equalizeHeight', equalizeHeight)
.directive('equalizeHeightAdd', equalizeHeightAdd);
equalizeHeight.$inject = ['$timeout'];
/* @ngInject */
function equalizeHeight() {
var directive = {
bindToController: true,
controller: ControllerName,
controllerAs: 'vm',
link: link,
restrict: 'A',
scope: {}
};
return directive;
function link(scope, element, attrs) {
}
}
ControllerName.$inject = ['$window', '$timeout'];
/* @ngInject */
function ControllerName($window, $timeout) {
var elements = [];
this.addElement = addElement;
this.removeElement = removeElement;
this.resize = resize;
activate();
function activate() {
angular.element($window).on('resize', function () {
angular.forEach(elements, function(el){
el[0].style.height = null;
});
resize();
});
}
function addElement(element){
elements.push(element);
console.log(elements.length);
}
function removeElement(element){
elements.splice(elements.indexOf(element),1);
}
// resize elements once the last element is found
function resize(){
$timeout(function(){
// find the tallest
var tallest = 0, height;
angular.forEach(elements, function(el){
height = el[0].offsetHeight;
if(height > tallest)
tallest = height;
});
// resize
angular.forEach(elements, function(el){
el[0].style.height = tallest + 'px';
});
}, 0);
}
}
/* @ngInject */
function equalizeHeightAdd(){
return {
restrict: 'A',
require: '^^equalizeHeight',
link: function(scope, element, attrs, ctrl_for){
// add element to list of elements
ctrl_for.addElement(element);
ctrl_for.resize();
element.on('$destroy', function () {
ctrl_for.removeElement(element);
ctrl_for.resize();
});
}
};
}
很抱歉,由于缺乏声誉,我无法在他的回答中添加评论,但我认为这是一个非常重要的补充。也很抱歉不同的格式化,但这是我在我的项目中使用它的方式,但基本上它是相同的。