更新Plunker 到项目: http ://plnkr.co/edit/oKB96szQhqwpKQbOGUDw?p=preview
我有一个使用 AngularJS Bootstrap 网格的 AngularJS 项目。我需要所有网格元素具有相同的大小,以便它们正确堆叠。我创建了一个 angularJs 指令,该指令在放置在所述网格元素中时自动调整网格元素的大小。我有 2 条指令为我执行此操作 指令 1:onload 指令 2:imageonload
指令 2 有效。如果网格元素使用图像,则在图像加载后,指令会触发一个事件,将网格元素高度发送到所有其他网格元素。如果通过事件发出的高度大于正在侦听事件的网格元素的高度,则侦听网格元素将其高度更改为更大的高度。这样最大的高度就变成了所有网格元素的高度。
指令 1 不起作用。这个放置在最外层的网格元素 html 元素上,并在元素加载时触发。问题是当元素加载并且调用 onload 指令时,AngularJS 还没有填写所述网格元素中的数据。结果是AngularJS数据绑定后的真实高度没有作为事件广播。
我想到的唯一解决方案(但没有尝试过)是将图像 url 添加到存在但没有任何数据的图像中,并将其放置在网格元素中(没有放置空白之前的任何图像)。然后我可以调用 imageonload 而不是 onload ,我很确定 angularjs 数据绑定到那时就会发生。
问题是这很hacky。我宁愿能够在网格元素中没有图像,并且能够调用我的自定义 onload 指令并让 onload 指令在 angularJS 数据绑定到网格元素中的所有数据绑定变量之后计算高度。
这是我的 imageonload 指令
.directive('imageonload', function($rootScope) {
return {
restrict: 'A',
link: function(scope, element, attrs) {
scope.heightArray = [];
scope.largestHeight = 50;
element.bind('load', function() {
broadcastThumbnailHeight();
});
scope.$on('imageOnLoadEvent', function(caller, value){
var el = angular.element(element);
var id = el.prop('id');
var pageName = el.prop('title');
if(pageName == value[0]){
if(scope.largestHeight < value[1]){
scope.largestHeight = value[1];
var nestedString = el.prop('alt');
if(nestedString == "")
nestedString = "1";
var nested = parseInt(nestedString);
nested = nested - 1;
var inte = 0;
var thumbnail = el["0"];
var finalThumbnailContainer = thumbnail.parentElement;
while(inte != nested){
finalThumbnailContainer = finalThumbnailContainer.parentElement;
inte++;
}
var innerEl = angular.element(finalThumbnailContainer);
var height = value[1];
innerEl.height(height);
}
}
});
scope.$on('findHeightAndBroadcast', function(){
broadcastThumbnailHeight();
});
scope.$on('resetThumbnailHeight', function(){
scope.largestHeight = 50;
});
function broadcastThumbnailHeight(){
var el = angular.element(element);
var id = el.prop('id');
var alt = el.prop('alt');
if(alt == "")
alt = "1";
var nested = parseInt(alt);
nested = nested - 1;
var pageName = el.prop('title');
var inte = 1;
var thumbnail = el["0"];
var finalThumbnail = thumbnail.parentElement;
while(inte != nested){
finalThumbnail = finalThumbnail.parentElement;
inte++;
}
var elZero = el["0"];
var clientHeight = finalThumbnail.clientHeight;
var arr = [];
arr[0] = pageName;
arr[1] = clientHeight;
$rootScope.$broadcast('imageOnLoadEvent', arr);
}
}
};
})
这是我的 onload 指令
.directive('onload', function($rootScope) {
return {
restrict: 'A',
link: function(scope, element, attrs) {
scope.largestHeight=100;
getHeightAndBroadcast();
scope.$on('onLoadEvent', function(caller, value){
var el = angular.element(element);
var id = el.prop('id');
var pageName = el.prop('title');
if(pageName == value[0]){
if(scope.largestHeight < value[1]){
scope.largestHeight = value[1];
var height = value[1];
el.height(height);
}
}
});
function getHeightAndBroadcast(){
var el = angular.element(element);
var h = el["0"].children;
var thumbnailHeightElement = angular.element(h);
var pageName = el.prop("title");
var clientHeight = thumbnailHeightElement["0"].clientHeight;
var arr = [];
arr[0] = pageName;
arr[1] = clientHeight;
if(clientHeight != undefined)
$rootScope.$broadcast('onLoadEvent', arr);
}
}
};
})
这是我使用 imageonload 的网格元素之一的示例。请注意图像 html 元素中的 imageonload 指令。这行得通。在网格元素的最外层 html 上还有一个 onload 指令。那是行不通的。我在 Firebug 中仔细检查了这一点,发现 onload 正在计算 AngularJS 数据绑定完成之前的高度。
<div class="thumbnail col-md-3" id="{{product.id}}" title="thumbnailAdminProductsGrid" onload>
<div class="row">
<div class="containerz">
<div class="row-fluid">
<div class="col-md-2"></div>
<div class="col-md-7">
<div class="textcenterinline">
<!--tag--><img class="img-responsive" id="{{product.id}}" title="imageAdminProductsGrid" alt=6 ng-src="{{product.baseImage}}" imageonload/><!--end tag-->
</div>
</div>
</div>
<div class="caption">
<div class="testing">
<div class="row-fluid">
<div class="col-md-12">
<h3 class="">
<!--tag--><a href="javascript:void(0);" ng-click="loadProductView('{{product.id}}')">{{product.name}}</a><!--end tag-->
</h3>
</div>
</div>
<div class="row-fluid">
<div class="col-md-12">
<p class="lead"><!--tag--> {{product.price}}</p><!--end tag-->
</div>
</div>
<div class="row-fluid">
<div class="col-md-12">
<p><!--tag-->{{product.inStock}} units available<!--end tag--></p>
</div>
</div>
<div class="row-fluid">
<div class="col-md-12">
<p class=""><!--tag-->{{product.generalDescription}}<!--end tag--></p>
</div>
</div>
<!--tag-->
<div data-ng-if="product.specialized=='true'">
<div class="row-fluid">
<div class="col-md-12" ng-repeat="varCat in product.varietyCategoriesAndOptions">
<b><h4>{{varCat.varietyCategoryName}}</h4></b>
<select ng-model="varCat.varietyCategoryOption" ng-options="value.varietyCategoryOptionId as value.varietyCategoryOptionValue for (key,value) in varCat.varietyCategoryOptions">
</select>
</div>
</div>
</div>
<!--end tag-->
<div class="row-fluid">
<div class="col-md-12">
<!--tag--><div ng-if="product.weight==0"><b>Free Shipping</b></div><!--end tag-->
</div>
</div>
</div>
</div>
</div>
</div>
这是我的一个网格元素之一的 html 示例,它只使用“onload”指令而不是“imageonload”
<div class="thumbnail col-md-3" title="thumbnailCouponGrid" onload>
<div class="innnerContainer">
<div class="text-center">
{{coupon.name}}
<br />
<br />
<b>Description</b>
<br />
{{coupon.description}}
<br />
<br />
<button class="btn btn-large btn-primary" ng-click="goToCoupon()">View Coupon Details</button>
</div>
</div>
imageonload 函数可能看起来有点混乱,因为我使用 img html 属性“alt”向指令指示 imageonload 放置在网格元素的最外层 html 下方多少层。我们必须拥有它,这样指令才能知道要在哪个 html 元素上设置新高度。我还使用“title”属性来设置此网格调整大小适用于哪个网格(这样您可以在同一页面上多次使用该指令用于不同的网格,并且不会触发错误网格的事件)。
有谁知道我如何在 angularJS 绑定到网格元素后调用“onload”指令?
为了完整起见,这里有 2 个图像(几乎看起来只有 1 个),第二个是包含具有图像并使用“imageonload”指令的网格元素的网格,第一个是包含不使用图像的网格元素的网格和仅使用“onload”指令。