Dan*_*edo 11 angularjs angularjs-directive
我正在尝试使用Angular JS指令来居中div的内容.
这是模板的简化版本:
<div id="mosaic" class="span12 clearfix" s-center-content>
<div ng-repeat="item in hits" id="{{item._id}}" >
</div>
</div>
Run Code Online (Sandbox Code Playgroud)
这是指令:
module.directive('sCenterContent', function() {
var refresh = function(element){
var aWidth= element.innerWidth();
var cWidth= element.children()[0].offsetWidth;
var cHeight= element.children()[0].offsetHeight;
var perRow= Math.floor(aWidth/cWidth);
var margin=(aWidth-perRow*cWidth)/2;
if(perRow==0){
perRow=1;
}
var top=0;
element.children().each(function(index, child){
$(child).css('margin-left','0px');
if((index % perRow)==0){
$(child).css('margin-left',margin+'px');
}
});
};
return {
link : function(scope, element, attrs) {
$(window).resize(function(event){
refresh(element);
});
}
};
});
Run Code Online (Sandbox Code Playgroud)
它基本上浮动一些内部div并为每行中的第一个div添加一个边距,因此内容居中.
调整浏览器大小时,这可以正常工作.当我尝试在初始化后进行刷新时出现问题.
我已尝试使用此问题中所见的帖子链接功能.预链接和后链接函数按预期顺序调用,但不会在具有s-center-content指令的elemenet的子节点被渲染之后调用.由于没有找到孩子,因此刷新调用失败.
如何打电话刷新以确保孩子们已被处理?
我认为使用angular的$ watch是一个更好,更优雅的解决方案:
link : function(scope, element, attrs) {
$(window).resize(function(event){
refresh(element);
});
var watchCount = 0,
unWatcher = $watch(
function() {
return $('*[s-center-content] img').length !== 0;
},
function() {
// ensure refresh isn't called the first time (before the count of elements is > 0)
if (++watchCount === 1) {
return;
}
refresh(element);
// stop watching the element now that refresh has been called
unWatcher();
}, true);
}
Run Code Online (Sandbox Code Playgroud)
关于停止观看:AngularJS:清除$ watch
这是一个反复出现的问题(某处有一个与此相关的问题,以及谷歌论坛中的一个帖子......)
Angular无法知道dom何时完成,它只能知道它调用的函数何时返回(并且任何promise都被解析).如果这些函数是异步的并且没有回调或承诺,则无法通知.
我已经看到它完成的方式(以及我完成它的方式)是使用setInterval定期检查DOM以查看它是否处于已完成状态.我讨厌这个解决方案,并会感激一个替代方案,但它确实完成了工作.
终于成功了!
我使用 livequery 插件并将以下行添加到链接方法的末尾:
$('*[s-center-content] > *').livequery( function(event){
refresh(element);
});
Run Code Online (Sandbox Code Playgroud)
我使用指令选择元素的任何第一级子元素(当前和未来),s-center-content并附加一个处理程序,该处理程序在元素添加到 DOM 时调用。
编辑
最后一点。我的内容布局主要取决于具有动态评估src属性的内部图像。因此,为了使其工作,我必须将代码更改为:
$('*[s-center-content] img').livequery( function(event){
$(this).load(function(){
refresh(element);
});
});
Run Code Online (Sandbox Code Playgroud)
将左浮动 div 居中的指令的完整代码如下。请注意,它依赖于向行中的第一个 div 添加计算出的边距。
module.directive('sCenterContent', function() {
var refresh = function(element){
var aWidth= element.innerWidth();
var cWidth= element.children()[0].offsetWidth;
var cHeight= element.children()[0].offsetHeight;
var perRow= Math.floor(aWidth/cWidth);
var margin=(aWidth-perRow*cWidth)/2;
if(perRow==0){
perRow=1;
}
var top=0;
element.children().each(function(index, child){
$(child).css('margin-left','0px');
if((index % perRow)==0){
$(child).css('margin-left',margin+'px');
}
});
};
return {
link : function(scope, element, attrs) {
$(window).resize(function(event){
refresh(element);
});
$('*[s-center-content] img').livequery( function(event){
$(this).load(function(){
refresh(element);
});
});
}
};
});
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
9405 次 |
| 最近记录: |