正如我在问题中所说,我想要实现的是仅相当于Angular中的代码:
jQuery的方式
$(document).ready(function(){
var windowHeight = $(window).height();
var headerHeight = $('header').height();
var footerHeight = $('footer').height();
var contentHeight = $('.content').height();
var paginationHeight = $('.pagination').height();
var footerMarginTop = (windowHeight - headerHeight - footerHeight) - (contentHeight + paginationHeight);
$('footer').on('content.loaded',function() {
if(footerMarginTop > 0) {
$(this).css('margin-top',footerMarginTop + 'px');
}
}
});
在准备好文档时,我必须在加载页面内容后,根据其他元素的高度计算设置页脚的页边距顶部.
在jQuery中思考很容易,但在Angular中,我没有找到其他方法,除了直接翻译它,如此,使用目录
角度方式
angular.module('myApp',[]).directive('FooterMargin',['$window','$document',function($window,$document){
return {
restrict: 'A',link: function(scope,element,attrs) {
var windowHeight = $window.innerHeight;
var headerHeight = $document[0].getElementById('header').offsetHeight;
var footerHeight = $document[0].getElementById('footer').offsetHeight;
var paginationHeight = $document[0].getElementById('pagination').offsetHeight;
var contentHeight = $document[0].getElementById('content').offsetHeight;
var footerMarginTop = (windowHeight - headerHeight - footerHeight) - (contentHeight + paginationHeight);
scope.$on('content.loaded',function(){
if(footerMarginTop > 0) {
attrs.$set('style','margin-top: ' + footerMarginTop + 'px');
}
}
});
}
};
}]);
我已经在我的元素中添加了ID以在Angular中检索它们,但即使它正在工作,在我看来这不是一个好方法,并且它也很难对它进行单元测试.
我不能在这个项目中使用jQuery,并且我已经使用Angular来获得更容易获得的事件的其他指令(比如模态和下拉)以令人满意的方式
你能帮助我理解如何以更好的Angular方式解决这个问题吗?
最佳答案
更Angular的方法可以是使用服务和另一个指令,该指令定义要选择的元素并将其高度设置为服务.
原文链接:https://www.f2er.com/html/426123.html然后,您的原始指令将从新服务中检索预先计算的高度.
在我的例子中,我使用工厂heightFactory作为服务.我还必须添加一个丑陋的超时来等待DOM元素正确呈现(并且有一个大小).我认为这是你想用范围实现的.在你的例子中也是$on(‘content.loaded’).
请注意标记中的指令用作set-height =“header”,例如,对于具有标题高度的元素.
在每个元素向服务注册其高度后,heightFactory.getMarginTop()的返回值将根据您的算法.
// this directive will ste the window height and retrieve the margin value from the height service
angular.module('myApp',[]).directive('footerMargin','heightFactory',heightFactory) {
return {
restrict: 'A',attrs) {
heightFactory.setHeight('window',$window.innerHeight);
// delay only for testing purposes,remove this
$window.setTimeout(function() {
attrs.$set('style','margin-top: ' + heightFactory.getMarginTop() + 'px');
console.log(heightFactory.getMarginTop());
},1000);
scope.$on('content.loaded',function() {
if (heightFactory.getMarginTop() > 0) {
attrs.$set('style','margin-top: ' + heightFactory.getMarginTop() + 'px');
}
});
}
};
}
]);
// this directive is used for each element,whichs size you want need for your calculation
angular.module('myApp').directive('setHeight',['heightFactory',function(heightFactory) {
return {
restrict: 'A',attrs) {
element.ready(function() {
heightFactory.setHeight(attrs['setHeight'],element[0].offsetHeight);
console.log(attrs['setHeight'] + ' set to ' + element[0].offsetHeight);
});
}
}
}
]);
// the algorithm for the margin is hardcoded,this service could also just return an object with the heights,and the algorithm would still be in your original directive. It depends on the use case imho.
angular.module('myApp').factory('heightFactory',[
function() {
var height = {};
return {
setHeight: function(element,value) {
height[element] = value;
},getMarginTop: function() {
return (height['window'] - height['header'] - height['footer']) - (height['content'] + height['pagination']);
}
};
}
]);
#header {
background-color: red;
}
#footer {
background-color: blue;
}
#pagination {
background-color: grey;
}