我在更新Angular中的元素上的css时遇到问题。我有一个div
,其中包含ng-repeat
生成的元素。包含这些元素的div
具有设置的高度,并附加ng-scrollbars
指令。当ng-scrollbars
中的元素超出其容器的高度时,div
会在div
内创建一个漂亮的滚动条。为此,它创建嵌套的内部div。因此,在这种情况下,如果嵌套内部div的高度大于其容器,则会生成一个滚动条,以便您可以滚动元素。
因此,我想在ng-repeat
列表中添加或删除项目。当发生这种情况时,我希望将额外的css添加到顶级div ,仅当由ng-scrollbars
生成的内部div超过顶级div的高度时。 (内部div的高度是ng-repeat
列表的实际高度,因为它包含ng-repeat
元素)
为此,我创建了两个指令,一个用于广播事件,另一个用于接收事件。广播事件的那个附加到每个ng-repeat
元素,并在创建或销毁元素时广播。这是为了检查ng-repeat
列表发生更改的时间。
接收广播的容器附加到顶级div
容器(包含由ng-scrollbar
生成的div的容器)并检查其高度与{{1}生成的内部div的关系},如果内部div的高度大于顶级div,则添加一些css。
我很抱歉,如果这看起来令人困惑,我的代码在附上评论附带说明,我希望能更好地解释一下:
ng-scrollbar
问题是app.directive('gtScrollLb', function () {
return {
restrict: 'A',
link: function (scope, elem, attrs) { //elem is the top level container of the ng-repeat elements
var scrollDiv = elem.children()[0]; //this is an internal div created by ng-scrollbars
var anotherScrollDiv = $(scrollDiv).children("#" + $(scrollDiv).attr("id") + "_container"); //another internal div created by ng-scrollbars
var id = attrs.gtScrollLb;
scope.$on(id + "-repeat-change",
function(newVal, oldVal) {
//check if ng-scrollbar div that now contains the ng-repeat elements
//has a greater height than the top level container
if ($(anotherScrollDiv).height() >= elem.height()) {
elem.css("border-bottom", "1px solid darkgrey");
} else {
elem.css("border-bottom", "");
}
}
);
}
};
});
app.directive('gtRepeatable', function () {
return {
restrict: 'A',
link: function (scope, elem, attrs) {
var id = attrs.gtRepeatable;
scope.$emit(id + "-repeat-change"); //event that item has been added by ng-repeat
var parent = scope.$parent;
elem.bind("$destroy",function(){
parent.$broadcast(id + "-repeat-change");//event that item has been destroyed by ng-repeat
});
}
}
});
元素在之前添加并销毁再次确定其内部容器的高度。因此,触发change事件时检查的高度实际上是内部容器的旧高度。
我需要以某种方式检查新的高度。我一直试图解决这个问题很长一段时间,非常感谢任何帮助。
修改
简而言之,在 ng-repeat完成并且DOM已渲染之后,我需要一个偶然的触发或观察发生。我在这里遇到的问题只是因为在呈现DOM
之前触发了事件。修改2
对于@vittore,他将此标记为重复。如果您实际上已经详细阅读了我的问题,您会发现您提议的副本与我的实际问题无关。这里ng-repeat
没有问题。 ng-scrollbars
工作正常。但有必要将其包含在描述中,因为它会影响我解决问题的方式。
答案 0 :(得分:0)
有一种方法可以在渲染最后一个循环元素时获取事件。请检查此链接:AngularJS - Manipulating the DOM after ng-repeat is finished
这里也是您提出的确切问题:ng-scrollbar is not working with ng-repeat
和重要的部分:
$scope.$on('loopLoaded', function(evt, index) {
if (index == $scope.me.length-1) {
$scope.$broadcast('rebuild:me');
}
});
答案 1 :(得分:0)
为了实现这一点,我最终使用了MutationObservers。我不得不使用两个,一个用于属性更改,一个用于子列表更改。
应该谨慎使用MutationObservers,如果不加以控制,它们会降低你的应用程序速度并导致严重的错误。我不小心造成无限循环进行异步调用。
最好只在更改DOM之前将它们连接起来,并让它们在进行更改后断开连接。